@ugfoundation/swaralipi-js 0.14.2 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/{batch-QEIW6XAA.js → batch-SYLHDJJL.js} +4 -4
- package/dist/{batch-QEIW6XAA.js.map → batch-SYLHDJJL.js.map} +1 -1
- package/dist/{chunk-CJI7A6AM.js → chunk-J5JYJL5N.js} +3 -3
- package/dist/{chunk-CJI7A6AM.js.map → chunk-J5JYJL5N.js.map} +1 -1
- package/dist/{chunk-WEXTZRRB.js → chunk-SPZO4573.js} +35 -7
- package/dist/chunk-SPZO4573.js.map +1 -0
- package/dist/{chunk-6AKH2NLW.js → chunk-WBYJUYI6.js} +3 -3
- package/dist/{chunk-6AKH2NLW.js.map → chunk-WBYJUYI6.js.map} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/convert/index.cjs +1 -1
- package/dist/convert/index.cjs.map +1 -1
- package/dist/convert/index.d.cts +1 -1
- package/dist/convert/index.d.ts +1 -1
- package/dist/convert/index.js +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{instruments-CfHu4bSQ.d.cts → instruments-C-KtHQiW.d.cts} +12 -9
- package/dist/{instruments-C3CbtYdm.d.ts → instruments-SoUQBZNd.d.ts} +12 -9
- package/dist/{lay-CFLy_wd_.d.ts → lay-CWlEhImP.d.ts} +1 -1
- package/dist/{lay-Bi87MnkT.d.cts → lay-CXhC-HRO.d.cts} +1 -1
- package/dist/player/index.cjs +93 -31
- package/dist/player/index.cjs.map +1 -1
- package/dist/player/index.d.cts +25 -5
- package/dist/player/index.d.ts +25 -5
- package/dist/player/index.js +62 -28
- package/dist/player/index.js.map +1 -1
- package/dist/spec/index.cjs +1 -1
- package/dist/spec/index.cjs.map +1 -1
- package/dist/spec/index.d.cts +12 -12
- package/dist/spec/index.d.ts +12 -12
- package/dist/spec/index.js +1 -1
- package/dist/viewer/index.cjs +43 -10
- package/dist/viewer/index.cjs.map +1 -1
- package/dist/viewer/index.d.cts +6 -4
- package/dist/viewer/index.d.ts +6 -4
- package/dist/viewer/index.js +10 -5
- package/dist/viewer/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-WEXTZRRB.js.map +0 -1
- package/dist/{schema-DyL0bMCf.d.ts → schema-DZag9qkF.d.cts} +36 -36
- package/dist/{schema-DyL0bMCf.d.cts → schema-DZag9qkF.d.ts} +36 -36
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/spec/taals.ts","../../src/spec/grace.ts","../../src/spec/svara.ts","../../src/player/pitch.ts","../../src/spec/lay.ts","../../src/player/lyrics.ts","../../src/convert/codec.ts","../../src/player/repeats.ts","../../src/player/schedule.ts","../../src/player/instruments.ts","../../src/player/player.ts","../../src/player/export.ts","../../src/player/midi.ts"],"names":["j","EPS","last","matra","el","sounds","LAY_TAIL_SEC","midiRange","off","mod","safeName","bytes"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Taal } from './schema.js';\n\n/**\n * Reference definitions for the taals the player will sample:\n * adachautaal, dadra, ektaal, jhaptaal, kehrwa, rupak, shashthi, teentaal,\n * jhampak, dhamaar, rupakra, khemta.\n *\n * `numBeats` and the `bhaags` given below are standard Hindustani taal theory.\n * `bhaags` is omitted where a single canonical division isn't well-agreed\n * (adachautaal) — we assert only what's uncontested. `sam` is beat 0 for all.\n *\n * Tabla loops live under `tabla/<id>/` by default; per-taal variation and\n * skip-bpm overrides (e.g. shashthi → `tabla/shashthi-pro/`) are in\n * instruments.ts's `TABLA_VARIATIONS`.\n */\nexport const TAALS = {\n dadra: { id: 'dadra', numBeats: 6, bhaags: [3, 3], sam: 0, khaali: [3] },\n kehrwa: { id: 'kehrwa', numBeats: 8, bhaags: [4, 4], sam: 0, khaali: [4] },\n rupak: { id: 'rupak', numBeats: 7, bhaags: [3, 2, 2], sam: 0, khaali: [0] },\n jhaptaal: { id: 'jhaptaal', numBeats: 10, bhaags: [2, 3, 2, 3], sam: 0, khaali: [5] },\n ektaal: { id: 'ektaal', numBeats: 12, bhaags: [2, 2, 2, 2, 2, 2], sam: 0, khaali: [2, 6] },\n adachautaal: { id: 'adachautaal', numBeats: 14, sam: 0 },\n choutaal: { id: 'choutaal', numBeats: 12, bhaags: [2, 2, 2, 2, 2, 2], sam: 0, khaali: [2, 6] }, // চৌতাল\n shashthi: { id: 'shashthi', numBeats: 6, bhaags: [2, 4], sam: 0 }, // ষষ্ঠী\n teora: { id: 'teora', numBeats: 7, bhaags: [3, 2, 2], sam: 0 }, // তেওরা\n teentaal: { id: 'teentaal', numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] },\n aratheka: { id: 'aratheka', numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] }, // আড়াঠেকা\n jhampak: { id: 'jhampak', numBeats: 5, bhaags: [3, 2], sam: 0 }, // ঝম্পক\n dhamaar: { id: 'dhamaar', numBeats: 14, bhaags: [5, 2, 3, 4], sam: 0, khaali: [7] }, // ধামার\n rupakra: { id: 'rupakra', numBeats: 8, bhaags: [3, 2, 3], sam: 0 }, // রূপকড়া\n khemta: { id: 'khemta', numBeats: 12, bhaags: [3, 3, 3, 3], sam: 0, khaali: [6] }, // খেমটা\n} as const satisfies Record<string, Taal>;\n\nexport type TaalId = keyof typeof TAALS;\n\n/**\n * The name a তালফেরতা song's header prints instead of one taal (Swarabitan /\n * Gitabitan's own word; gitabitan.io's taxonomy spells it তাল-ফেরতা). The\n * taals themselves live on the rows (`row.taal`).\n */\nexport const TAAL_FERTA = 'তালফেরতা';\n\n/** Whether a printed taal name is the তালফেরতা heading (either spelling). */\nexport function isTaalFerta(name: string | undefined): boolean {\n return name !== undefined && name.normalize('NFC').replace(/[\\s-]/g, '') === TAAL_FERTA;\n}\n\n/**\n * Whether two taal marks name the same accompaniment — the তালফেরতা test.\n * `null` (মুক্তছন্দ) and `undefined` (no taal) are only equal to themselves.\n * Compared by value: a row restating the taal in force is not a change.\n */\nexport function sameTaal(a: Taal | null | undefined, b: Taal | null | undefined): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n return a.id === b.id && a.numBeats === b.numBeats && a.variation === b.variation && String(a.bhaags) === String(b.bhaags);\n}\n","/**\n * কণ / রেশ readers. Zod-free on purpose: the viewer and the player import\n * this directly (the `spec/index.js` barrel would drag zod into their\n * browser bundles — see `taals.ts` for the same rule).\n */\nimport type { Grace, Note, Svara } from './schema.js';\n\n/** Normalise a grace payload to its note list; the legacy tuple is one note. */\nexport function graceNotes(grace: Grace | undefined): Note[] {\n if (grace === undefined) return [];\n return typeof grace[0] === 'string' ? [{ svara: grace as Svara }] : (grace as Note[]);\n}\n","/**\n * Which svaras admit which alteration — স and প are অচল (immovable), ম has\n * only its তীব্র (কড়ি) form, and র গ ধ ন only their কোমল form. The notation\n * fonts encode exactly this (no glyph exists for a কোমল প), so a flag the\n * sheet cannot draw must not move the pitch either.\n *\n * Zod-free on purpose: the viewer and the player import this directly (the\n * `spec/index.js` barrel would drag zod into their browser bundles — see\n * `taals.ts` and `grace.ts` for the same rule).\n */\nimport type { SvaraLetter } from './schema.js';\n\nexport function hasKomal(letter: SvaraLetter): boolean {\n return letter === 'r' || letter === 'g' || letter === 'd' || letter === 'n';\n}\n\nexport function hasTivra(letter: SvaraLetter): boolean {\n return letter === 'm';\n}\n","/**\n * Pure svara → pitch math for the player. No Tone, no audio — unit-testable\n * in plain Node and shared by the scheduler.\n *\n * The model: a tonic (Sa) pitch-class + a per-note scale degree + octave\n * register + komal/tivra/microtone accidentals → an absolute MIDI number,\n * which the Tone.Sampler pitch-shifts from the nearest santoor sample.\n */\nimport { graceNotes } from '../spec/grace.js';\nimport { hasKomal, hasTivra } from '../spec/svara.js';\nimport type { Note, Octave, SvaraLetter } from '../spec/index.js';\n\n/** Octave register offset in octaves, relative to madhyam (middle). */\nexport const OCTAVE_OFFSET: Record<Octave, number> = {\n 'ati-mandra': -2,\n mandra: -1,\n madhyam: 0,\n taar: 1,\n 'ati-taar': 2,\n};\n\n/**\n * Shuddha (natural) scale degrees in semitones above Sa — the Bilawal/major\n * thaat that Rabindrasangeet swaralipi notates against. `d` = dha, `n` = ni\n * (standard sargam letter convention).\n */\nexport const SHUDDHA: Record<SvaraLetter, number> = {\n s: 0,\n r: 2,\n g: 4,\n m: 5,\n p: 7,\n d: 9,\n n: 11,\n};\n\n/** Sharp-spelled pitch-class names, index = semitone 0–11. */\nconst SHARP_NAMES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] as const;\n\n/** Pitch-class lookup. Accepts sharps (`C#`, `Cs`, `cs`) and flats (`Db`). */\nconst PITCH_CLASS: Record<string, number> = {\n c: 0,\n 'c#': 1,\n db: 1,\n d: 2,\n 'd#': 3,\n eb: 3,\n e: 4,\n 'e#': 5,\n fb: 4,\n f: 5,\n 'f#': 6,\n gb: 6,\n g: 7,\n 'g#': 8,\n ab: 8,\n a: 9,\n 'a#': 10,\n bb: 10,\n b: 11,\n 'b#': 0,\n cb: 11,\n};\n\n/**\n * Parse a tonic string to a pitch-class 0–11. Accepts `C`, `C#`, `Db`, and\n * the player/sample lowercase-`s` sharp form (`cs`, `Cs`); case-insensitive.\n * Unknown input falls back to 0 (C).\n */\nexport function parseTonic(tonic: string | undefined): number {\n if (!tonic) return 0;\n const key = tonic.trim().toLowerCase().replace(/s/g, '#');\n return PITCH_CLASS[key] ?? 0;\n}\n\n/**\n * Semitone of a note relative to Sa (degree + accidentals), ignoring octave.\n * Returns null when the note carries no pitch (rest/sustain-hold/bar).\n *\n * Microtones (অল্পকোমল/অতিকোমল) are approximated to the komal pitch — a\n * documented v1 limitation (the sampler can't bend a sub-komal microtone\n * cleanly per note); matches the viewer's placeholder treatment.\n */\nexport function svaraSemitone(note: Note): number | null {\n if (note.svara === undefined) return null;\n const [, letter] = note.svara;\n let semi = SHUDDHA[letter];\n // Only alter what the notation can actually draw: স/প are অচল and ম has no\n // কোমল form, so a stray flag on one of those must sound as written (the\n // viewer falls back to the shuddha glyph — see glyphs.ts).\n if ((note.komal === true || note.microtone !== undefined) && hasKomal(letter)) semi -= 1;\n if (note.tivra === true && hasTivra(letter)) semi += 1;\n return semi;\n}\n\n/**\n * Absolute MIDI for a note, or null when it has no pitch. madhyam Sa lands on\n * the tonic in octave `baseOctave` (C4 = MIDI 60). Out-of-sample registers\n * are produced by the Sampler pitch-shifting from the nearest recorded note.\n */\nexport function svaraToMidi(note: Note, tonicPc: number, baseOctave = 4): number | null {\n const semi = svaraSemitone(note);\n if (semi === null || note.svara === undefined) return null;\n const [octave] = note.svara;\n return (baseOctave + 1 + OCTAVE_OFFSET[octave]) * 12 + tonicPc + semi;\n}\n\n/** MIDI of a কণ/রেশ grace: one pitch per grace svara, in written order.\n * Goes through `svaraToMidi`, so a komal/tivra grace sounds as written (the\n * legacy tuple form carries no accidentals and is shuddha by construction). */\nexport function graceMidis(\n grace: Note['kan'],\n tonicPc: number,\n baseOctave = 4,\n): number[] {\n return graceNotes(grace)\n .map((n) => svaraToMidi(n, tonicPc, baseOctave))\n .filter((m): m is number => m !== null);\n}\n\n/** MIDI → Tone note name (`C#4`). */\nexport function midiToSampleName(midi: number): string {\n const pc = ((midi % 12) + 12) % 12;\n const octave = Math.floor(midi / 12) - 1;\n return `${SHARP_NAMES[pc]}${octave}`;\n}\n\n/** MIDI → santoor sample filename stem (`cs4`): lowercase, `#` → `s`. */\nexport function sampleFileName(midi: number): string {\n return midiToSampleName(midi).toLowerCase().replace('#', 's');\n}\n\n/**\n * Logistic S-curve on [0, 1], normalised so f(0) = 0 and f(1) = 1.\n *\n * A মীড় is **not** a linear ramp. The hand (or the voice) accelerates away\n * from the source pitch and decelerates into the target — \"if the pull is too\n * fast, the melody loses its vocal quality; if it is too slow, the note dies\n * before reaching its destination\". That S shape is the established model for\n * portamento pitch contours (Yang & Chew's logistic fit, ISMIR 2016), and its\n * coefficient has a direct musical meaning: `steepness` is how abruptly the\n * pitch leaves one svara for the next.\n */\nexport function sCurve(x: number, steepness = 8): number {\n const t = Math.min(Math.max(x, 0), 1);\n const logistic = (u: number) => 1 / (1 + Math.exp(-steepness * (u - 0.5)));\n const lo = logistic(0);\n return (logistic(t) - lo) / (logistic(1) - lo);\n}\n","/**\n * লয় (laya) — the tempo tier a passage is sung at.\n *\n * Hindustani names the three tiers বিলম্বিত / মধ্য / দ্রুত (vilambit = slow,\n * madhya = medium, drut = fast), and Rabindrasangeet swaralipi uses the same\n * words: NLTR prints \"বিলম্বিত লয়:\" / \"দ্রুত লয়:\" at the head of the line\n * where the tempo changes (see `printedLay`).\n *\n * `meta.bpm` is the **দ্রুত** tempo — the fast one — so the tiers are\n * multipliers ≤ 1 on it and a document with no লয় marks plays exactly as it\n * did before this field existed.\n *\n * Zod-free on purpose: the viewer, player and creator import this directly\n * (the `spec/index.js` barrel would drag zod into their browser bundles — the\n * same rule as `taals.ts` and `grace.ts`).\n */\nimport type { Note, Row } from './schema.js';\n\nexport type Lay = 'drut' | 'madhya' | 'vilambit';\n\nexport const LAYS: readonly Lay[] = ['drut', 'madhya', 'vilambit'];\n\n/**\n * ### The tempo factors — change them HERE.\n *\n * Fraction of `meta.bpm` each tier is played at. Consumers override per\n * document (`meta.laySpeeds`) or per player/export call (`laySpeeds`), so\n * these are only the fallback.\n */\nexport const LAY_SPEEDS: Record<Lay, number> = {\n drut: 1,\n madhya: 0.75,\n vilambit: 0.5,\n};\n\nexport type LaySpeeds = Partial<Record<Lay, number>>;\n\n/** Resolve the factors actually in force: call option → document → default. */\nexport function resolveLaySpeeds(doc?: LaySpeeds, opt?: LaySpeeds): Record<Lay, number> {\n return { ...LAY_SPEEDS, ...doc, ...opt };\n}\n\n/**\n * The printed লয় mark: the leading lyric-only cells NLTR writes a tempo\n * change as (\"বিলম্বিত\" \"লয়:\"). Reading it means the 1738 already-converted\n * songs change tempo without being reconverted or edited.\n *\n * ponytail: matches the first word only, and only in the leading annotation\n * position where real lyrics never sit — so 'মধ্যমান' (a taal) can't trip it.\n * If a source ever writes the mark elsewhere in the row, give it `row.lay`.\n */\nconst PRINTED: Record<string, Lay> = { দ্রুত: 'drut', মধ্য: 'madhya', বিলম্বিত: 'vilambit' };\n\nexport function printedLay(notes: Note[]): Lay | undefined {\n const first = notes[0];\n if (first === undefined || first.lyric === undefined) return undefined;\n for (const k of Object.keys(first)) if (k !== 'lyric') return undefined;\n return PRINTED[first.lyric.normalize('NFC')];\n}\n\n/** The লয় this row switches to, if any: the explicit field wins over the\n * source's printed mark. `undefined` = carry on at the previous tier. */\nexport function rowLay(row: Row): Lay | undefined {\n return row.lay ?? printedLay(row.notes);\n}\n","/**\n * Where in the song's text each note sings, and which notes sing a stretch of it.\n *\n * A swaralipi's lyric row is phonetic and split into syllables (আ|বা|র্, চি|ৎ|ত,\n * ৹ for a held syllable), and it often writes a refrain out again. So the\n * notation's letters are aligned to the text by global alignment\n * (Needleman–Wunsch) that may also jump to any word start, the way JumpDTW lets\n * a score re-enter its own repeat blocks (Fremerey, Müller & Clausen, ISMIR\n * 2010). Over gitabitan's 1827 song/notation pairs it aligns 97.9 % of the\n * notation's letters; the rest are songs whose text is only a fragment.\n */\nimport type { Swaralipi } from '../spec/schema.js';\nimport type { Visit } from './repeats.js';\nimport type { PlayEvent } from './schedule.js';\n\n/** `part.row.note` → the `[start, end)` UTF-16 offsets of the text it sings. */\nexport type LyricMap = Map<string, [number, number]>;\n\n/** The text's lines as the events sing them, each word timed by its first note — an LRC's\n * cues. A line sung again (a repeat) is a new cue. Words are the text's whitespace runs. */\nexport function lyricCues(\n events: PlayEvent[],\n map: LyricMap,\n text: string,\n): { beat: number; words: { beat: number; text: string }[] }[] {\n const tokens = [...text.matchAll(/\\S+/g)].map((m) => ({\n text: m[0],\n start: m.index,\n end: m.index + m[0].length,\n line: text.slice(0, m.index).split('\\n').length - 1,\n }));\n const cues: { beat: number; line: number; last: number; words: { beat: number; text: string }[] }[] = [];\n for (const ev of events) {\n const span = map.get(ev.path);\n const index = span ? tokens.findIndex((t) => t.start <= span[0] && span[0] < t.end) : -1;\n if (index < 0) continue;\n const token = tokens[index]!;\n let cue = cues.at(-1);\n if (!cue || cue.line !== token.line || index < cue.last) {\n cue = { beat: ev.beat, line: token.line, last: -1, words: [] };\n cues.push(cue);\n }\n if (index !== cue.last) {\n cue.words.push({ beat: ev.beat, text: token.text });\n cue.last = index;\n }\n }\n return cues.map(({ beat, words }) => ({ beat, words }));\n}\n\n/** Play only the notes singing these `[start, end)` stretches of the text, in order. */\nexport interface Excerpt {\n lyrics: LyricMap;\n ranges: [number, number][];\n}\n\nconst MATCH = 2;\nconst GAP = 1;\nconst JUMP = 4;\nconst RUN = 3;\n// 98 % of the corpus's misspelt syllables run under 8 unplaced letters.\nconst STRAY = 8;\nconst EPS = 1e-6;\nconst [DIAG, UP, LEFT, JUMPED] = [1, 2, 3, 4];\n\n/** The letters two spellings share: virama, nukta and ৹ dropped, খণ্ড ত read as ত. */\nconst letters = (s: string): string =>\n s\n .normalize('NFD')\n .replace(/ৎ/g, 'ত')\n .replace(/[^\\p{L}\\p{M}]|[়্]/gu, '')\n .toLowerCase();\n\n/** Each note of `doc` that sings a letter of `text`, with the stretch of `text` it sings. */\nexport function alignLyrics(doc: Swaralipi, text: string): LyricMap {\n const sung: { letter: string; path: string }[] = [];\n doc.parts.forEach((part, p) =>\n part.rows.forEach((row, r) =>\n row.notes.forEach((note, i) => {\n for (const letter of letters(note.lyric ?? '')) sung.push({ letter, path: `${p}.${r}.${i}` });\n }),\n ),\n );\n const said: { letter: string; from: number; to: number }[] = [];\n const starts: number[] = [];\n let at = 0;\n let gap = true;\n for (const ch of text) {\n const ls = letters(ch);\n if (ls === '') {\n gap ||= /[\\s\\p{P}]/u.test(ch);\n // A virama / nukta / joiner belongs to the letter before it, so a span never splits a conjunct's marks off.\n if (/[\\p{M}\\p{Cf}]/u.test(ch) && said.at(-1)?.to === at) said.at(-1)!.to += ch.length;\n } else {\n if (gap) starts.push(said.length);\n gap = false;\n }\n for (const letter of ls) said.push({ letter, from: at, to: at + ch.length });\n at += ch.length;\n }\n\n const n = sung.length;\n const m = said.length;\n const w = m + 1;\n const from = new Uint8Array((n + 1) * w);\n const best = new Int32Array(n + 1);\n // Before any letter is sung the text starts at its top; anywhere else costs a jump.\n let prev = new Int32Array(w).fill(-(2 ** 30));\n prev[0] = 0;\n let cur = new Int32Array(w);\n /** Jump from the row's best cell to every word start, then let the row skip text letters. */\n const settle = (i: number, row: Int32Array): void => {\n for (let j = 1; j < w; j++) if (row[j]! > row[best[i]!]!) best[i] = j;\n for (const s of starts) {\n if (row[best[i]!]! - JUMP > row[s]!) {\n row[s] = row[best[i]!]! - JUMP;\n from[i * w + s] = JUMPED;\n }\n }\n for (let j = 1; j < w; j++) {\n if (row[j - 1]! - GAP > row[j]!) {\n row[j] = row[j - 1]! - GAP;\n from[i * w + j] = LEFT;\n }\n }\n };\n settle(0, prev);\n for (let i = 1; i <= n; i++) {\n cur[0] = prev[0]! - GAP;\n from[i * w] = UP;\n for (let j = 1; j < w; j++) {\n const diag = prev[j - 1]! + (sung[i - 1]!.letter === said[j - 1]!.letter ? MATCH : -GAP);\n const up = prev[j]! - GAP;\n cur[j] = Math.max(diag, up);\n from[i * w + j] = diag >= up ? DIAG : UP;\n }\n best[i] = 0;\n settle(i, cur);\n [prev, cur] = [cur, prev];\n }\n\n // Trace back from the best end, collecting the letters that agree.\n const pairs: [number, number][] = [];\n let j = 0;\n for (let k = 1; k < w; k++) if (prev[k]! > prev[j]!) j = k;\n for (let i = n; i > 0; ) {\n const step = from[i * w + j];\n if (step === JUMPED) j = best[i]!;\n else if (step === LEFT) j--;\n else if (step === UP) i--;\n else {\n if (sung[i - 1]!.letter === said[j - 1]!.letter) pairs.push([i - 1, j - 1]);\n i--;\n j--;\n }\n }\n pairs.reverse();\n // A lone agreeing letter (a vowel sign past the text's end) is chance, not\n // the same word: only RUN sung letters agreeing in a row place a note. A row\n // carries on into the text's next letter, or across a jump to a word start,\n // so a short word sung over and over (আয়্ আয়্) holds.\n const wordStart = new Set(starts);\n const follows = (k: number): boolean =>\n pairs[k]![0] === pairs[k - 1]![0] + 1 && (pairs[k]![1] === pairs[k - 1]![1] + 1 || wordStart.has(pairs[k]![1]));\n const out: LyricMap = new Map();\n /** The text letter each note's span ends on: a syllable grows only by the letter after it. */\n const last = new Map<string, number>();\n for (let a = 0, b = 1; a < pairs.length; a = b++) {\n while (b < pairs.length && follows(b)) b++;\n if (b - a < RUN) continue;\n for (const [s, t] of pairs.slice(a, b)) {\n const { path } = sung[s]!;\n const { from: lo, to: hi } = said[t]!;\n const span = out.get(path);\n if (span === undefined) out.set(path, [lo, hi]);\n else if (t === last.get(path)! + 1) span[1] = hi;\n else continue;\n last.set(path, t);\n }\n }\n return out;\n}\n\nconst mod = (a: number, n: number): number => ((a % n) + n) % n;\nconst sings = (v: Visit): boolean => v.note.svara !== undefined || v.note.sustain === true;\n\n/**\n * The visits of `order` that sing `excerpt`, and the matra (in `at`, each\n * visit's written matra in the whole song) the first one starts on.\n *\n * Each range plays the song's form while its words stay inside the range — a\n * `{ }` repeat, a return to the asthayi — from its first sung note to the last\n * one before the words leave it. Rests and held syllables go with it; a range\n * the notation does not sing is left out. Between two ranges a rest keeps the\n * next one on the beat it has in the whole song, so the taal never breaks.\n */\nexport function excerptVisits(\n order: Visit[],\n at: number[],\n { lyrics, ranges }: Excerpt,\n cycle: (v: Visit) => number | undefined,\n): { visits: Visit[]; matra: number } {\n // Where each visit sings in the text; -1 for words the text does not have\n // (another stanza, another song): a stretch of STRAY or more letters the\n // alignment left unplaced. A shorter one is a syllable spelt otherwise.\n const pos = order.map((v) => lyrics.get(`${v.p}.${v.r}.${v.i}`)?.[0]);\n for (let a = 0; a < order.length; a++) {\n if (pos[a] !== undefined || letters(order[a]!.note.lyric ?? '') === '') continue;\n let b = a;\n let stray = 0;\n while (b < order.length && pos[b] === undefined) stray += letters(order[b++]!.note.lyric ?? '').length;\n if (stray >= STRAY) pos.fill(-1, a, b);\n a = b;\n }\n\n const visits: Visit[] = [];\n let first: number | undefined;\n let end = 0;\n for (const [lo, hi] of ranges) {\n const inside = (k: number): boolean | undefined => (pos[k] === undefined ? undefined : pos[k]! >= lo && pos[k]! < hi);\n const a = order.findIndex((_, k) => inside(k) === true);\n if (a < 0) continue;\n let b = a + 1;\n while (b < order.length && inside(b) !== false) b++;\n while (b - 1 > a && !sings(order[b - 1]!)) b--;\n const n = cycle(order[a]!);\n if (first === undefined) first = a;\n else if (n !== undefined) {\n // ponytail: phase is the whole song's matra mod this taal's cycle, so a jump across a তালফেরতা change is approximate.\n const gap = mod(at[a]! - at[end]!, n);\n if (gap > EPS) visits.push({ ...order[end - 1]!, note: { rest: true, durationMatra: gap } });\n }\n visits.push(...order.slice(a, b));\n end = b;\n }\n return { visits, matra: first === undefined ? 0 : at[first]! };\n}\n","/**\n * The Swarabitan ASCII codec: decode one grid-cell text into spec `Note`s.\n *\n * NLTR renders notation through the legacy \"Swarabitan\" webfont, which maps\n * ASCII to akarmatrik glyphs. The table below was derived by dumping every\n * glyph of `Swarabitan.woff` (tools/font-dump/) and cross-checking against\n * the Swarabitan legend scans, the rendered reference screenshot of song\n * 4270, and corpus-wide token statistics. Evidence per assignment:\n *\n * Letters (full-size glyphs):\n * s=স r=র g=গ m=ম p=প q=ধ n=ন — the seven shuddha letters\n * d=দ (komal dha) t=জ্ঞ (komal ga) — legend: কোমল র—ঋ, কোমল গ—জ্ঞ,\n * k=ক্ষ (tivra ma) u=ণ (komal ni) — কড়ি ম—ক্ষ, কোমল ধ—দ, কোমল ন—ণ\n * v=ঋ (komal re)\n * Modifiers:\n * f = রেফ above → taar octave (zero-width high combining mark)\n * h = হসন্ত below → mandra octave (low combining mark; corpus nh/uh/dh/ph)\n * leading '-' = no new vowel attack (melisma; lyric row shows ৹)\n * trailing 'a' = the আ-কার matra carrier; k letter-units in one cell\n * share it → k notes of 1/k matra each\n * UPPERCASE letter = small raised form = কণ (kan/grace) prefix; takes its\n * own f/h (corpus: Sfua, NHsa, QHpha); width ratios ~0.65\n * confirm uppercase↔lowercase pairing\n * Structurals (own cells):\n * A = thin full-height bar → দাঁড়ি vibhag separator (fixed columns)\n * l = serif danda I → cycle end; ll / single-glyph L = section\n * %=সা &=নি — precomposed one-matra forms (rare)\n * Known-but-kept-raw marks (drawn pieces the spec doesn't model yet):\n * w x = left/right ends of a long under-arc; E J j y $ < > = _ = arc/line\n * fill segments; | = thin yugal-dari stop mark (mostly annotation rows);\n * digits/!/@ (+f/F sam tick) = taal beat labels; b=× o O e ` + , . i : ;\n * = dots/ticks/duration marks; B C * ^ ~ c = rare precomposed/legacy forms.\n *\n * Decoding never throws: any chunk outside the grammar becomes a raw-only\n * note and is reported as unknown — zero data loss by construction.\n */\nimport type { Note, Octave, Svara, SvaraLetter } from '../spec/index.js';\n\nexport interface CellDecode {\n notes: Note[];\n /** Chunks that failed the grammar (reported, kept as raw notes). */\n unknownTokens: string[];\n /** Chunks understood but intentionally left raw (marks, beat labels …). */\n knownRawTokens: string[];\n /** True if at least one chunk decoded to a semantic note. */\n decoded: boolean;\n}\n\ninterface LetterDef {\n letter: SvaraLetter;\n komal?: true;\n tivra?: true;\n}\n\n/** ASCII → svara letter (+ komal/tivra). The five non-shuddha glyph letters\n * are distinct characters in akarmatrik, so the flags live here. */\nconst LETTERS: Record<string, LetterDef> = {\n s: { letter: 's' },\n r: { letter: 'r' },\n g: { letter: 'g' },\n m: { letter: 'm' },\n p: { letter: 'p' },\n q: { letter: 'd' }, // ধ — shuddha dha\n n: { letter: 'n' },\n d: { letter: 'd', komal: true }, // দ\n t: { letter: 'g', komal: true }, // জ্ঞ\n k: { letter: 'm', tivra: true }, // ক্ষ\n u: { letter: 'n', komal: true }, // ণ\n v: { letter: 'r', komal: true }, // ঋ\n};\n\n/** Standalone structural tokens (bars are handled by the bar-run rule). */\nconst STRUCTURALS: Record<string, () => Note> = {\n '%': () => ({ svara: ['madhyam', 's'] }), // precomposed সা\n '&': () => ({ svara: ['madhyam', 'n'] }), // precomposed নি\n};\n\n/**\n * Bar/bracket runs: `l`(I danda) `ll`/`L`(II) `llll`/`LL`(IIII) `A`(দাঁড়ি),\n * plus composites the corpus writes into one cell — `l[]l` / `L[]L` (the\n * legend's \"I [ ] I\" return-to-asthayi-with-changed-notes marker), `AA`,\n * and `-A` (the previous note's continuation dash sharing the dari's cell).\n */\nconst BAR_RUN_RE = /^(-)?([lLA[\\]]+)$/;\n\nfunction decodeBarRun(body: string): Note[] | undefined {\n const m = body.match(BAR_RUN_RE);\n if (!m || !/[lLA]/.test(m[2]!)) return undefined;\n const notes: Note[] = [];\n if (m[1]) notes.push({ sustain: true });\n const run = m[2]!;\n let i = 0;\n while (i < run.length) {\n const ch = run[i]!;\n if (ch === 'l' || ch === 'L') {\n let j = i;\n while (j < run.length && run[j] === ch) j++;\n const strokes = (j - i) * (ch === 'L' ? 2 : 1);\n notes.push({ bar: strokes >= 4 ? 'quad' : strokes >= 2 ? 'double' : 'single' });\n i = j;\n } else if (ch === 'A') {\n notes.push({ bar: 'dari' });\n i++;\n } else {\n notes.push({ brackets: [{ kind: 'alt', edge: ch === '[' ? 'open' : 'close' }] });\n i++;\n }\n }\n return notes;\n}\n\n/** Marks/labels that are understood but deliberately preserved raw-only. */\nconst KNOWN_RAW_RE = [\n /^[wxyjEJ$<>=_]+$/, // arc & line drawing segments\n /^\\|+$/, // thin yugal-dari stop mark\n /^[0-9!@#]{1,2}[fF]?:?$/, // beat-number labels incl. 10–16 (sam tick = f/F, e.g. 1f / 1F / 2:)\n /^[oOe`+,.;:iI~^*bcBCWXYFHZz'\"?]$/, // dots, ticks, duration marks, legacy forms\n];\n\nconst OPEN_BRACKETS: Record<string, 'repeat' | 'skip' | 'alt'> = {\n '{': 'repeat',\n '(': 'skip',\n '[': 'alt',\n};\nconst CLOSE_BRACKETS: Record<string, 'repeat' | 'skip' | 'alt'> = {\n '}': 'repeat',\n ')': 'skip',\n ']': 'alt',\n};\n\nfunction octaveOf(mark: string | undefined): Octave {\n if (mark === 'f' || mark === 'F') return 'taar';\n if (mark === 'h' || mark === 'H') return 'mandra';\n return 'madhyam';\n}\n\n/**\n * Body grammar of one chunk (brackets already peeled):\n *\n * [beat-digit] ['-'] [KAN] unit* ['a'] [fh] [i:] [KAN] [beat-digit]\n *\n * where unit = letter [fh] and KAN = uppercase letter [fFhH]. Corpus\n * realities beyond the canonical `[-]KAN unit+ a` shape:\n * - octave mark typed after the আ-কার: `saf` ≡ `sfa` (taar sa) — the reph\n * applies to the last unit;\n * - trailing `i` (two stacked rings, ঃ-shaped) or `:` (two lozenges — a\n * different glyph) after the matra: a **matra sign worth ½**, the আ-কার's\n * half-brother (legend `রাঃ` = 1½, `সঃ` = ½; corpus rows fit their taal\n * cycle 114:19 in favour of that reading over \"articulation only\"). The\n * durations below still ignore it — they split the cell evenly among its\n * units, so `qinqi` decodes ⅓⅓⅓ where the sheet says ½ ¼ ¼. The viewer\n * reads the marks off `raw` and draws them right (viewer/render.ts\n * `rawMarks`); playback is what the even split still gets wrong;\n * - trailing KAN (`-aR`): an anticipatory grace drawn at the cell's right\n * edge, leading into the next note — attached to this cell's last note;\n * - the cut mark may also lead or sit between units (`-iqi`, `mpimi`);\n * - leading `z` = blank spacer glyph (empty outline in the font) — skipped.\n * A standalone detached `a` (no hyphen) is a 1-matra rest per the legend\n * (\"হাইফেন-বর্জিত … বিরামের মাত্রা\").\n */\nconst BODY_RE =\n /^([0-9!@][fF]?)?([zj]*)(-)?([i:])?(?:([SRGMPQNDTKUV])([fFhH])?)?((?:[srgmpqndtkuv][fh]?[i:]?)+)?(a)?([fh])?([i:])?(?:([SRGMPQNDTKUV])([fFhH])?)?([0-9!@][fF]?)?(-)?$/;\n\nfunction decodeChunk(chunk: string): { notes: Note[]; kind: 'decoded' | 'known' | 'unknown' } {\n // 1. Peel brackets.\n const opens: ('repeat' | 'skip' | 'alt')[] = [];\n const closes: ('repeat' | 'skip' | 'alt')[] = [];\n let body = chunk;\n while (body.length > 0) {\n const kind = OPEN_BRACKETS[body[0]!];\n if (kind === undefined) break;\n opens.push(kind);\n body = body.slice(1);\n }\n while (body.length > 0) {\n const kind = CLOSE_BRACKETS[body[body.length - 1]!];\n if (kind === undefined) break;\n closes.unshift(kind);\n body = body.slice(0, -1);\n }\n\n const finish = (notes: Note[], kind: 'decoded' | 'known' | 'unknown') => {\n if (notes.length === 0) notes.push({});\n const first = notes[0]!;\n const last = notes[notes.length - 1]!;\n if (opens.length > 0) first.brackets = [...opens.map((kind_) => ({ kind: kind_, edge: 'open' as const })), ...(first.brackets ?? [])];\n if (closes.length > 0) last.brackets = [...(last.brackets ?? []), ...closes.map((kind_) => ({ kind: kind_, edge: 'close' as const }))];\n return { notes, kind };\n };\n\n // 2. Bracket-only chunk → raw carrier for the bracket edges.\n if (body === '') return finish([{}], 'decoded');\n\n // 3. Bar/bracket runs, then the remaining standalone structurals.\n const barRun = decodeBarRun(body);\n if (barRun) return finish(barRun, 'decoded');\n const structural = STRUCTURALS[body];\n if (structural) return finish([structural()], 'decoded');\n\n // 4. Known raw marks.\n if (KNOWN_RAW_RE.some((re) => re.test(body))) return finish([{}], 'known');\n\n // 5. Note grammar.\n const m = body.match(BODY_RE);\n if (m) {\n const [, , , hyphen, , kanLetter, kanOct, unitsStr, aakar, postOct, , trailKan, trailKanOct] = m;\n const attachKan = (note: Note, letter: string, oct: string | undefined) => {\n const def = LETTERS[letter.toLowerCase()]!;\n // NOTE: the spec kan is a plain [octave, letter] tuple, so a komal\n // kan letter (e.g. D = small দ) is projected onto its shuddha\n // letter; the exact glyph stays recoverable from `raw`.\n note.kan = [octaveOf(oct?.toLowerCase()), def.letter] as Svara;\n };\n if (unitsStr) {\n const units = unitsStr.match(/[srgmpqndtkuv][fh]?/g) ?? [];\n const notes: Note[] = units.map((unit) => {\n const def = LETTERS[unit[0]!]!;\n const note: Note = { svara: [octaveOf(unit[1]), def.letter] as Svara };\n if (def.komal) note.komal = true;\n if (def.tivra) note.tivra = true;\n if (units.length > 1) note.durationMatra = 1 / units.length;\n return note;\n });\n const last = notes[notes.length - 1]!;\n // Post-আকার octave mark (`saf`): applies to the last unit unless it\n // already carries its own mark.\n if (postOct && last.svara![0] === 'madhyam') {\n last.svara = [octaveOf(postOct), last.svara![1]] as Svara;\n }\n if (hyphen) notes[0]!.sustain = true;\n if (kanLetter) attachKan(notes[0]!, kanLetter, kanOct);\n if (trailKan && last.kan === undefined) attachKan(last, trailKan, trailKanOct);\n return finish(notes, 'decoded');\n }\n if (aakar) {\n // '-a' = sustain (hold previous pitch, no new attack);\n // bare detached 'a' = one-matra rest (legend: hyphen-less matra sign).\n const note: Note = hyphen ? { sustain: true } : { rest: true };\n if (trailKan) attachKan(note, trailKan, trailKanOct);\n else if (kanLetter) attachKan(note, kanLetter, kanOct);\n return finish([note], 'decoded');\n }\n if (hyphen && !kanLetter && !trailKan) {\n // A bare continuation dash (`-`, `-i`) — the আ-কার is implied.\n return finish([{ sustain: true }], 'decoded');\n }\n // Kan without units, or digit-edges with no note between — keep raw.\n }\n\n return finish([{}], 'unknown');\n}\n\n/**\n * Decode one cell's text. Multi-chunk cells (whitespace-separated) emit\n * notes in order; the first note of each chunk carries that chunk's source\n * text in `raw`, so joining a cell's `raw` values with spaces reproduces\n * the normalized cell text (the lossless property tests rely on this).\n */\nexport function decodeCell(text: string): CellDecode {\n const chunks = text.split(/\\s+/).filter((c) => c.length > 0);\n const out: CellDecode = { notes: [], unknownTokens: [], knownRawTokens: [], decoded: false };\n for (const chunk of chunks) {\n const { notes, kind } = decodeChunk(chunk);\n notes[0]!.raw = chunk;\n if (kind === 'decoded') out.decoded = true;\n else if (kind === 'known') out.knownRawTokens.push(chunk);\n else out.unknownTokens.push(chunk);\n out.notes.push(...notes);\n }\n return out;\n}\n","/**\n * The order a swaralipi is **sung** in, as opposed to the order it is written.\n * Swarabitan's legend (স্বরবিতান pp. ১৩৫–১৩৬, gitabitan.io/bn/swaralipi/how-to-read/):\n *\n * - `{ }` is sung twice; `( )` inside it is left out the second time, and the\n * `[ ]` notes written above stand in for the notes under them.\n * - II at a kali's end sends the singer back to the asthayi's opening II, on\n * to the ‖ stop mark, then into the next kali: D.S. al Fine, with ‖ as the\n * Fine. I[ ]I / II[ ]II make that return sing the `[ ]` notes.\n * - IIII written as one stroke group ends the song: no return.\n *\n * The notation is written for this order, so every jump lands where the grid\n * expects it: the \"৹ ৹ ৹\" after a kali-end II is the rest of the cycle the ‖\n * broke off, which is what keeps a looping tabla on sam. Whatever the marks\n * leave unsaid (no ‖, a stray bracket) is sung as written.\n */\nimport { decodeCell } from '../convert/codec.js';\nimport type { Bracket, Note, Swaralipi } from '../spec/schema.js';\n\n/** One note as sung: where it is written (for highlights) and what sounds. */\nexport interface Visit {\n p: number;\n r: number;\n i: number;\n /** The written note, or a `[ ]` note standing in for it on a repeat. */\n note: Note;\n}\n\n/**\n * A raw the codec could not decode but which still **holds a matra** in the\n * source grid: it carries svara letters or the আ-কার carrier `a` (e.g. a\n * mistyped `` `-a `` / `frsfa` / `PUda`). Bracket, bar-glyph and beat-label\n * carriers contain none of these, so they stay timeless. Dropping these\n * columns outright ran the melody ahead of the তাল from that point on.\n */\nconst UNDECODED_CELL = /[srgmpqnvtduka]/i;\n\n/** A column that produces no sound and no time advance (bar, bracket-only,\n * carrier, structural raw). Mirrors the viewer's non-pitched, non-rest\n * classes. */\nexport const isSilent = (n: Note): boolean =>\n n.svara === undefined &&\n n.rest !== true &&\n n.sustain !== true &&\n !(n.raw !== undefined && UNDECODED_CELL.test(n.raw));\n\n/** ‖ written above a note: অবসানের চিহ্ন, where a return to the asthayi stops. */\nconst STOP_MARK = /^\\|+$/;\nconst EPS = 1e-6;\n\ninterface Token extends Visit {\n timed: boolean;\n}\n\nconst edges = (n: Note, kind: Bracket['kind'], edge: Bracket['edge']): number =>\n n.brackets?.filter((b) => b.kind === kind && b.edge === edge).length ?? 0;\nconst sounds = (n: Note): boolean => n.svara !== undefined || n.rest === true || n.sustain === true;\nconst matra = (notes: Note[]): number => notes.reduce((sum, n) => sum + (n.durationMatra ?? 1), 0);\n\n/** Every note of `doc` in the order it is sung. */\nexport function playOrder(doc: Swaralipi): Visit[] {\n const tokens: Token[] = [];\n doc.parts.forEach((part, p) =>\n part.rows.forEach((row, r) =>\n row.notes.forEach((note, i) => tokens.push({ p, r, i, note, timed: note.bar === undefined && !isSilent(note) })),\n ),\n );\n const { asthayi, stop, returns } = form(tokens);\n const changed = changedNotes(tokens);\n const out: Visit[] = [];\n // The token of the last note sung.\n let last = -1;\n\n /** Sing tokens lo..hi-1: each `{ }` twice, its `( )` only the first time. */\n const sing = (lo: number, hi: number, useChanged: boolean): void => {\n const repeats: { open: number; again: boolean }[] = [];\n // Matra of written notes a longer `[ ]` note already sang over.\n let owed = 0;\n for (let k = lo; k < hi; ) {\n const t = tokens[k]!;\n if (edges(t.note, 'repeat', 'open') > 0 && repeats.at(-1)?.open !== k) repeats.push({ open: k, again: false });\n const again = repeats.at(-1)?.again === true;\n const skipTo = again && edges(t.note, 'skip', 'open') > 0 ? skipEnd(tokens, k, hi) : -1;\n if (skipTo >= 0) {\n if (edges(tokens[skipTo]!.note, 'repeat', 'close') > 0) repeats.pop();\n k = skipTo + 1;\n owed = 0;\n continue;\n }\n if (owed > EPS && t.timed) owed -= matra([t.note]);\n else {\n const sub = useChanged || again ? changed.get(k) : undefined;\n // A `[ ]` note shorter than the one it replaces would pull the melody off sam.\n const fits = sub !== undefined && matra(sub) >= matra([t.note]) - EPS;\n for (const note of fits ? sub : [t.note]) out.push({ p: t.p, r: t.r, i: t.i, note });\n if (t.timed) last = k;\n owed = fits ? matra(sub) - matra([t.note]) : 0;\n }\n const loop = edges(t.note, 'repeat', 'close') > 0 ? repeats.at(-1) : undefined;\n if (loop !== undefined && !loop.again) {\n loop.again = true;\n k = loop.open;\n owed = 0;\n continue;\n }\n if (loop !== undefined) repeats.pop();\n k++;\n }\n };\n\n let from = 0;\n for (const ret of returns) {\n sing(from, ret.resume, false);\n // Singing that already stopped at ‖ \"takes up another kali\" there: a ‖ at\n // the asthayi's own close, or a `{ }` whose second pass skips from ‖ to `}`.\n if (last !== stop) sing(asthayi, stop + 1, ret.changed);\n from = ret.resume;\n }\n sing(from, tokens.length, false);\n return out;\n}\n\n/**\n * The song's form: where the asthayi starts (its opening II, else the top),\n * where a return stops (the first ‖ in the asthayi), and the token after each\n * kali-end II or I[ ]I. No ‖ → no returns: the notation then does not say how\n * far back to sing.\n */\nfunction form(tokens: Token[]): { asthayi: number; stop: number; returns: { resume: number; changed: boolean }[] } {\n // A II opens a kali when its row's singing comes after it, and closes one\n // when the singing comes before; mid-row, it alternates with the last II.\n const first = new Map<string, number>();\n const last = new Map<string, number>();\n tokens.forEach((t, k) => {\n if (!t.timed) return;\n const row = `${t.p}.${t.r}`;\n if (!first.has(row)) first.set(row, k);\n last.set(row, k);\n });\n const opens: number[] = [];\n let opening = false;\n tokens.forEach((t, k) => {\n if (t.note.bar !== 'double') return;\n const row = `${t.p}.${t.r}`;\n const before = (first.get(row) ?? Infinity) < k;\n const after = (last.get(row) ?? -1) > k;\n opening = before !== after ? after : !opening;\n if (opening) opens.push(k);\n });\n\n // A kali ends on a closing II, or on I[ ]I / II[ ]II (an empty `[ ]` among\n // the bars); a run of bars holding IIII ends the song instead.\n const returns: { resume: number; changed: boolean }[] = [];\n for (let k = 0; k < tokens.length; k++) {\n let at = -1;\n let open = false;\n let changed = false;\n let end = false;\n for (; k < tokens.length && !tokens[k]!.timed; k++) {\n const n = tokens[k]!.note;\n if (n.bar === 'quad') end = true;\n if (n.bar === 'double' && !opens.includes(k)) at = k;\n if (edges(n, 'alt', 'open') > 0) open = true;\n if (open && edges(n, 'alt', 'close') > 0) {\n at = k;\n changed = true;\n }\n }\n if (at >= 0 && !end) returns.push({ resume: at + 1, changed });\n }\n\n const top = opens[0];\n const asthayi = top !== undefined && top < (returns[0]?.resume ?? Infinity) ? top : 0;\n // The asthayi ends at its own closing II, or where the next kali opens. A ‖\n // with nothing sung after it is the song's own end (\"এইখানে একেবারে থামিবে\"),\n // not where a return stops.\n const asthayiEnd = Math.min(returns[0]?.resume ?? Infinity, opens.find((k) => k > asthayi) ?? Infinity, tokens.length);\n const lastSung = tokens.reduce((last, t, k) => (t.timed ? k : last), -1);\n const stop = tokens.findIndex(\n (t, k) =>\n k >= asthayi && k < asthayiEnd && k < lastSung && t.note.above?.some((a) => STOP_MARK.test(a.raw ?? '')) === true,\n );\n return { asthayi, stop, returns: stop < 0 ? [] : returns };\n}\n\n/**\n * The `[ ]` notes written above each column, by token: what is sung there on\n * a repeat. A span runs from the above-row `[` to its `]`; a column under it\n * with nothing above keeps its own note.\n */\nfunction changedNotes(tokens: Token[]): Map<number, Note[]> {\n const out = new Map<number, Note[]>();\n let row = '';\n let inside = false;\n tokens.forEach((t, k) => {\n // ponytail: a span is closed at the row's end — no corpus span crosses a row.\n if (row !== `${t.p}.${t.r}`) {\n row = `${t.p}.${t.r}`;\n inside = false;\n }\n const notes: Note[] = [];\n for (const above of t.note.above ?? []) {\n // An older converter left a few cells like `[sfa]` undecoded: read them as it now would.\n const read = above.raw !== undefined && !sounds(above) && above.brackets === undefined;\n for (const a of read ? decodeCell(above.raw!).notes : [above]) {\n if (edges(a, 'alt', 'open') > 0) inside = true;\n if (inside && sounds(a)) notes.push(a);\n if (edges(a, 'alt', 'close') > 0) inside = false;\n }\n }\n if (notes.length > 0) out.set(k, notes);\n });\n return out;\n}\n\n/** The token closing the `( )` that opens at `k`, or -1 if it never closes. */\nfunction skipEnd(tokens: Token[], k: number, hi: number): number {\n for (let depth = 0, j = k; j < hi; j++) {\n depth += edges(tokens[j]!.note, 'skip', 'open') - edges(tokens[j]!.note, 'skip', 'close');\n if (depth <= 0) return j;\n }\n return -1;\n}\n","/**\n * Pure spec-doc → playback timeline. No Tone, no audio — the player turns\n * this `Schedule` into Transport events, but it is fully unit-testable on its\n * own and mirrors the viewer's spec-driven (not raw-driven) reading.\n *\n * Timing unit is the মাত্রা (matra / beat). One global beat cursor runs across\n * every part and row: NLTR \"systems\" (rows) are wraps of one continuous line,\n * and parts (asthayi → antara …) play back-to-back, so the music never pauses\n * at a row or part boundary.\n *\n * Each audible column carries the same `data-note` path the viewer emits\n * (`part.row.note`, note = absolute index into `row.notes`; see\n * src/viewer/render.ts), so `SwaralipiPlayer` can drive `highlight()` directly.\n */\nimport type { Note, Swaralipi, Taal } from '../spec/index.js';\nimport { resolveLaySpeeds, rowLay, type Lay, type LaySpeeds } from '../spec/lay.js';\nimport { sameTaal } from '../spec/taals.js';\nimport { graceMidis, parseTonic, svaraToMidi } from './pitch.js';\nimport { excerptVisits, type Excerpt } from './lyrics.js';\nimport { isSilent, playOrder } from './repeats.js';\n\nexport interface PlayEvent {\n /** Onset in matra from the start of the document. */\n beat: number;\n /** Ring length in matra (extended by following আ-কার holds). */\n durationBeats: number;\n /** Pitch as MIDI, or null for a rest / আ-কার hold column. */\n midi: number | null;\n /** MIDI of each কণ grace on this column, in written order (empty = none). */\n kan: number[];\n /** MIDI of each রেশ grace on this column, in written order (empty = none). */\n resh: number[];\n /** `part.row.note` highlight path. */\n path: string;\n kind: 'note' | 'rest' | 'sustain';\n /**\n * মীড়: this pitch is reached by **gliding** from the previous pitched event,\n * not by a new attack. The two (or more) notes are one continuous sound whose\n * pitch travels — see `meendContinuations`. Consumers pair an attack with its\n * targets via `glideTargets`.\n */\n glide?: true;\n}\n\n/**\n * One accompaniment stretch of the timeline: a লয় and a তাল held constant.\n * A new segment starts wherever either changes — they are independent marks.\n * `scale` is the fraction of the base bpm the passage sounds at, and it is\n * exactly the factor a looping accompaniment must change its own tempo by —\n * `beat` × secondsPerBeat gives its start in seconds. Always at least one\n * segment, the first at beat 0.\n */\nexport interface TempoSegment {\n /** Start, in schedule beats (see PlayEvent.beat). */\n beat: number;\n /** End, in schedule beats (= the next segment's start, or totalBeats). */\n endBeat: number;\n scale: number;\n lay: Lay;\n /** তাল in force: `meta.taal` until a row's `taal` changes it. `null` = an\n * explicit মুক্তছন্দ passage; `undefined` = the document names no taal. */\n taal?: Taal | null;\n}\n\nexport interface Schedule {\n events: PlayEvent[];\n /** Total length in matra (the cursor's final value). */\n totalBeats: number;\n /**\n * অনাগত/anacrusis offset: beats the melody must be pushed later so the song's\n * সম (sam) lands on a cyclic accompaniment's sam. Many songs begin part-way\n * through the তাল cycle (the notation's first beat-label is `2`/`3`… and the\n * সম tick `1f`/`2f`… appears a few beats in) — without a shift the pickup note\n * would sound on the tabla's sam. Derived purely from the notation's own সম\n * tick position and `meta.taal.numBeats`; 0 when the song starts on sam or has\n * no sam tick. The player/exporter apply it only when a rhythm actually loops.\n */\n pickupBeats: number;\n /** লয় / তাল stretches, in order and gapless. One entry (drut, scale 1,\n * `meta.taal`) for a document that never changes either — i.e. every\n * document written before `row.lay` / `row.taal` existed. */\n tempo: TempoSegment[];\n}\n\nexport interface ScheduleOptions {\n /** Tonic; accepts `C`, `C#`, `cs`… (see parseTonic). Default C. */\n tonic?: string;\n /** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */\n baseOctave?: number;\n /** Override the লয় tempo factors (see LAY_SPEEDS / meta.laySpeeds). */\n laySpeeds?: LaySpeeds;\n /** Apply লয় at all. Default true. The staff view sets it false: it reads\n * `durationBeats` as written note values, where a 0.75 stretch is not a\n * writable duration. */\n lay?: boolean;\n /** Sing the song's form (see playOrder): each `{ }` twice, `( )` only the\n * first time, the `[ ]` notes on the repeat, and back to the asthayi at each\n * kali's end. Default false — the written order, which the staff view and\n * anything grouping events by row rely on; the player and the audio/MIDI\n * exports turn it on. */\n repeats?: boolean;\n /** Play only the notes singing these stretches of the song's text (see\n * alignLyrics / excerptVisits). Taken from the order above. */\n excerpt?: Excerpt;\n}\n\n/**\n * Below-annotation raws that are মীড় arc drawing segments (codec known-raw):\n * `w`/`x` are the left/right curled ends, the rest are straight fill pieces.\n * Lives here rather than in the viewer because **both** need it and the viewer\n * may import the player (never the reverse — that would pull Tone into it).\n */\nexport const ARC_RAW_RE = /^[wWxXyYjJeEzZ$=_<>`\\\\]+$/;\nexport const isArcRaw = (raw: string | undefined): raw is string =>\n raw !== undefined && ARC_RAW_RE.test(raw);\n\n/** The spec's `meend` as the corpus's own arc marks; `both` = close, then re-open. */\nconst MEEND_MARKS: Record<NonNullable<Note['meend']>, string> = { start: 'w', end: 'x', both: 'xw' };\n\n/**\n * Note indices in one row that lie under a মীড় arc **without opening it** —\n * i.e. every note the pitch glides *to*, as opposed to the one it glides\n * *from*.\n *\n * Swarabitan's legend defines the under-arc as \"কোনো এক স্বর যখন আর এক স্বরে\n * বিশেষরূপে গড়াইয়া যায়\" — when one svara *rolls into* another (example:\n * ণা‿পা). It is one continuous phonation, which is why 90 % of the corpus's\n * 7 419 arcs end on a melisma (a note under the *same* held syllable, lyric ৹).\n * So the notes under an arc must not be re-articulated: only the first sounds.\n *\n * Two encodings feed the same scan — the converter's below-row `w`/`x` raws\n * (every meend in the 1738-song corpus) and the spec's own `meend: start|end`\n * (what the creator writes). A cell may carry both ends (`xw` =\n * close then re-open, `wx` = an arc drawn inside the one cell), so marks are\n * read **in order** — reading them as an unordered set left a `wx` arc open and\n * slurred the next eighteen notes into a single slide. Arcs are resolved per row — exactly one arc in the\n * whole corpus wraps across a row, so cross-row state would not pay for itself.\n */\nexport function meendContinuations(notes: Note[]): Set<number> {\n const out = new Set<number>();\n /** Notes seen since the arc opened — committed only once it closes. */\n let pending: number[] | undefined;\n notes.forEach((note, i) => {\n let marks = note.meend ? MEEND_MARKS[note.meend] : '';\n for (const b of note.below ?? []) if (isArcRaw(b.raw)) marks += b.raw;\n let marked = false;\n for (const ch of marks) {\n if (ch === 'x' || ch === 'X') {\n // Closes here: this note and everything since the open are targets.\n if (pending !== undefined) for (const k of [...pending, i]) out.add(k);\n pending = undefined;\n marked = true;\n } else if (ch === 'w' || ch === 'W') {\n pending = []; // opens here: this note is the source, not a target\n marked = true;\n }\n }\n if (!marked && pending !== undefined) pending.push(i);\n });\n // An arc left open at the row's end is a notation slip (5 in 1738 songs), not\n // a glide: committing it would slur the whole rest of the line into one\n // 16-beat slide. The viewer still draws it as a system-wrap continuation.\n return out;\n}\n\n/**\n * The glide targets belonging to the attack at `events[i]`: the pitched events\n * that follow it flagged `glide`. Silent columns (আ-কার holds) are transparent\n * — the note is still ringing through them — but a rest ends the phrase.\n * Consumers skip events that are themselves `glide` (already consumed here).\n */\nexport function glideTargets(events: PlayEvent[], i: number): PlayEvent[] {\n const out: PlayEvent[] = [];\n for (let j = i + 1; j < events.length; j++) {\n const ev = events[j]!;\n if (ev.kind === 'rest') break;\n if (ev.midi === null) continue;\n if (ev.glide !== true) break;\n out.push(ev);\n }\n return out;\n}\n\n/** Schedule beats between a grace and its column's start; consecutive graces step by it. */\nexport const GRACE_STEP = 0.12;\n\n/**\n * When each grace of `ev` sounds, in written order, mirrored around the\n * column's start: a কণ (written left of its svara) touches just before it, a\n * রেশ (written right) just after — so on a hold or rest column they touch under\n * whatever is still ringing. Not at the column's end: every grace is a fresh\n * strike, and one struck just before the next column is heard as its কণ.\n */\nexport function graceTouches(ev: PlayEvent): { midi: number; beat: number }[] {\n // ponytail: a fixed step, so several graces on a very short column spill past\n // it (two রেশ on a 1/5-matra note); scale the step by column length if needed.\n return [\n ...ev.kan.map((midi, g) => ({ midi, beat: ev.beat - GRACE_STEP * (ev.kan.length - g) })),\n ...ev.resh.map((midi, g) => ({ midi, beat: ev.beat + GRACE_STEP * (g + 1) })),\n ];\n}\n\n/**\n * One line of the sheet as the practice controls move by it: a `part.row`\n * with at least one timed column. It runs from its first event to the next\n * line's (the last one to `totalBeats`), so a line's trailing bars and holds\n * belong to it. A row sung twice (a repeat, a return to the asthayi) is two\n * lines with one `row`.\n */\nexport interface Line {\n /** `part.row` — the viewer's `data-row`. */\n row: string;\n /** Index of the line's first event. */\n first: number;\n beat: number;\n endBeat: number;\n}\n\nconst rowOf = (path: string): string => path.split('.').slice(0, 2).join('.');\nconst noteOf = (path: string): number => Number(path.split('.')[2] ?? 0);\n/** Written order of two `part.row` keys. */\nexport const byRow = (a: string, b: string): number => {\n const [ap = 0, ar = 0] = a.split('.').map(Number);\n const [bp = 0, br = 0] = b.split('.').map(Number);\n return ap - bp || ar - br;\n};\n\n/** The schedule's events grouped into sheet lines, in play order. A row of\n * bars and annotations only has no events, so it is not a line; a repeat that\n * jumps back within a row starts a new one. */\nexport function scheduleLines(schedule: Pick<Schedule, 'events' | 'totalBeats'>): Line[] {\n const lines: Line[] = [];\n let note = Infinity;\n schedule.events.forEach((ev, i) => {\n const n = noteOf(ev.path);\n if (lines.at(-1)?.row !== rowOf(ev.path) || n < note) lines.push({ row: rowOf(ev.path), first: i, beat: ev.beat, endBeat: 0 });\n note = n;\n });\n lines.forEach((line, k) => (line.endBeat = lines[k + 1]?.beat ?? schedule.totalBeats));\n return lines;\n}\n\n/** Index of the line holding event `i`. */\nexport function lineAt(lines: Line[], i: number): number {\n let k = 0;\n while (k + 1 < lines.length && lines[k + 1]!.first <= i) k++;\n return k;\n}\n\n/**\n * The line `path` (`part.row[.note]`) names — its own row, else the next row\n * that sounds — sung at the pass nearest line `near` (-1: the first pass).\n * -1 when no line is at or after it.\n */\nexport function lineFor(lines: Line[], path: string, near: number): number {\n let row: string | undefined;\n for (const line of lines) if (byRow(line.row, rowOf(path)) >= 0 && (row === undefined || byRow(line.row, row) < 0)) row = line.row;\n let best = -1;\n lines.forEach((line, k) => {\n if (line.row === row && (best < 0 || Math.abs(k - near) < Math.abs(best - near))) best = k;\n });\n return best;\n}\n\n/**\n * The event a tap or a seek to `path` (`part.row.note`, or `part.row` for the\n * line's start) should start from: the first event at or after that note in\n * its own line, else the line's last one — a closing bar belongs to its line,\n * not the next — else the next line's first. A line sung more than once\n * resolves to the pass nearest event `near` (default: the first pass). A note\n * reached by a মীড় glide has no attack of its own, so the glide's source is\n * returned instead. -1 when nothing sounds from there on.\n */\nexport function eventAt(events: PlayEvent[], path: string, near = -1): number {\n const lines = scheduleLines({ events, totalBeats: 0 });\n const k = lineFor(lines, path, near < 0 ? -1 : lineAt(lines, near));\n if (k < 0) return -1;\n const end = lines[k + 1]?.first ?? events.length;\n let i = lines[k]!.first;\n if (lines[k]!.row === rowOf(path)) while (i < end - 1 && noteOf(events[i]!.path) < noteOf(path)) i++;\n while (i > 0 && events[i]!.glide === true) i--;\n return i;\n}\n\n/** A সম beat-tick: a beat-label digit carrying the reph tick (`1f`/`2F`…). It\n * marks the sam wherever it lands; the digit is a within-line vibhag number, so\n * only the trailing f/F (not the value) identifies sam. Labels live on a note's\n * `above` annotations (see the converter's beat-label handling). */\nconst SAM_TICK = /^\\d+[fF]$/;\n\n/**\n * Walk a document into a flat, time-ordered list of play events.\n *\n * - svara note → an attack at the cursor; advances by `durationMatra ?? 1`.\n * - rest → a silent column that still advances the cursor.\n * - sustain **with** svara (melisma) → a fresh attack (the pitch moves under\n * a held vowel); advances.\n * - sustain **without** svara (আ-কার hold) → no attack, but the previous\n * audible note's ring is extended; still emitted (midi null) so the lyric\n * column highlights; advances.\n * - a svara under a মীড় arc (but not the note the arc opened on) → still its\n * own event, flagged `glide`: the pitch is reached by sliding from the\n * previous attack rather than by striking again (see meendContinuations).\n * - bar / bracket-only / carrier / structural raw → ignored (no event, no\n * advance); an *undecoded* notation cell (see isSilent) instead plays as a\n * rest, so it keeps its matra and the তাল stays aligned.\n *\n * Written order by default; with `repeats` the walk follows the sung order\n * (playOrder), so a column sung twice is two events with one path.\n */\nexport function buildSchedule(doc: Swaralipi, opts: ScheduleOptions = {}): Schedule {\n const tonicPc = parseTonic(opts.tonic ?? doc.meta.tonic);\n const baseOctave = opts.baseOctave ?? 4;\n const events: PlayEvent[] = [];\n let cursor = 0;\n /** Index in `events` of the last pitched attack, for hold-extension. */\n let lastPitched = -1;\n\n // লয় and তাল: a row's mark holds until another row changes it, in written\n // order — so a repeat or a return to the asthayi sings each row at its own\n // tempo and taal, not at whatever the jump came from. `scale` < 1 stretches\n // the written matra over more schedule beats, which is what makes the\n // passage sound slower at one transport tempo.\n const speeds = resolveLaySpeeds(doc.meta.laySpeeds, opts.laySpeeds);\n const withLay = opts.lay !== false;\n const tempo: TempoSegment[] = [{ beat: 0, endBeat: 0, scale: 1, lay: 'drut', taal: doc.meta.taal }];\n const rows = new Map<string, { scale: number; lay: Lay; taal: Taal | null | undefined; glides: Set<number> }>();\n let scale = 1;\n let layNow: Lay = 'drut';\n let taal: Taal | null | undefined = doc.meta.taal;\n doc.parts.forEach((part, p) =>\n part.rows.forEach((row, r) => {\n const lay = withLay ? rowLay(row) : undefined;\n if (lay !== undefined && speeds[lay] !== scale) {\n scale = speeds[lay];\n layNow = lay;\n }\n if (row.taal !== undefined) taal = row.taal;\n rows.set(`${p}.${r}`, { scale, lay: layNow, taal, glides: meendContinuations(row.notes) });\n }),\n );\n\n const order =\n opts.repeats === true\n ? playOrder(doc)\n : doc.parts.flatMap((part, p) => part.rows.flatMap((row, r) => row.notes.map((note, i) => ({ p, r, i, note }))));\n // Each visit's matra from the song's start, and the first সম tick's (see\n // SAM_TICK) — *written* matra, so the anacrusis maths stays independent of\n // the লয়, and an excerpt keeps every note on the beat it has in the song.\n const at = [0];\n let samMatra: number | undefined;\n for (const { note } of order) {\n const m = at[at.length - 1]!;\n if (samMatra === undefined && note.above?.some((a) => a.raw !== undefined && SAM_TICK.test(a.raw))) samMatra = m;\n at.push(note.bar === undefined && !isSilent(note) ? m + (note.durationMatra ?? 1) : m);\n }\n const { visits, matra } = opts.excerpt\n ? excerptVisits(order, at, opts.excerpt, (v) => rows.get(`${v.p}.${v.r}`)!.taal?.numBeats)\n : { visits: order, matra: 0 };\n let rowNow = '';\n for (const { p, r, i, note } of visits) {\n const row = rows.get(`${p}.${r}`)!;\n if (rowNow !== `${p}.${r}`) {\n rowNow = `${p}.${r}`;\n // The two marks are independent, so a segment starts wherever either moves.\n const last = tempo[tempo.length - 1]!;\n if (row.scale !== last.scale || !sameTaal(row.taal, last.taal)) {\n const seg: TempoSegment = { beat: cursor, endBeat: cursor, scale: row.scale, lay: row.lay, taal: row.taal };\n // Two marks with nothing between them are one switch, not a 0-beat segment.\n if (last.beat === cursor) tempo[tempo.length - 1] = seg;\n else {\n last.endBeat = cursor;\n tempo.push(seg);\n }\n }\n }\n if (note.bar !== undefined || isSilent(note)) continue;\n const path = `${p}.${r}.${i}`;\n const written = note.durationMatra ?? 1;\n const dur = written / row.scale;\n // Any column that takes time can carry graces, a hold or rest included.\n const kan = graceMidis(note.kan, tonicPc, baseOctave);\n const resh = graceMidis(note.resh, tonicPc, baseOctave);\n\n if (note.svara !== undefined) {\n // svara note or melisma — a real attack, unless a মীড় glides into it.\n events.push({\n beat: cursor,\n durationBeats: dur,\n midi: svaraToMidi(note, tonicPc, baseOctave),\n kan,\n resh,\n path,\n kind: note.sustain === true ? 'sustain' : 'note',\n ...(row.glides.has(i) && lastPitched >= 0 ? { glide: true as const } : {}),\n });\n lastPitched = events.length - 1;\n } else if (note.sustain === true) {\n // আ-কার hold — extend the ringing note, emit a silent highlight column.\n if (lastPitched >= 0) events[lastPitched]!.durationBeats += dur;\n events.push({ beat: cursor, durationBeats: dur, midi: null, kan, resh, path, kind: 'sustain' });\n } else {\n // rest.\n events.push({ beat: cursor, durationBeats: dur, midi: null, kan, resh, path, kind: 'rest' });\n }\n cursor += dur;\n }\n\n // Anacrusis: shift the melody so its sam falls on a cyclic sam. If the first\n // note is at matra M and sam at S in an N-beat cycle, the shift is\n // (M − S) mod N (a partial-to-full cycle count-in; 0 when the song already\n // starts on sam). No সম tick: the song's first note is sam. The opening\n // taal's cycle — the one the count-in is played in.\n const numBeats = tempo[0]!.taal?.numBeats;\n const pickupMatra =\n numBeats !== undefined && numBeats > 0 ? (((matra - (samMatra ?? 0)) % numBeats) + numBeats) % numBeats : 0;\n tempo[tempo.length - 1]!.endBeat = cursor;\n\n // The count-in is played at the tempo the song *starts* in.\n return { events, totalBeats: cursor, pickupBeats: pickupMatra / tempo[0]!.scale, tempo };\n}\n","/**\n * Tone.js instrument/asset factories. Tone is **injected** (never imported\n * here) so this module — like the scheduler — stays free of a static `tone`\n * dependency; the player passes the dynamically-imported module in.\n *\n * Melodic instruments are a small registry (INSTRUMENTS) of Tone.Sampler\n * note→file maps + where to fetch them. `piano` (CC-BY Salamander) is the\n * default and CDN-hosted, as are `harmonium`/`violin`/`flute` (CC-BY,\n * tonejs-instruments); `santoor` is local (under the player's `soundsBaseUrl`).\n * Consumers can register more (e.g. a self-hosted sitar) via the player's\n * `customInstruments` option — true sampled sitar/sarod/sarangi/esraj have no\n * free web set, only commercial Kontakt libraries.\n *\n * Asset layout under `soundsBaseUrl`:\n * santoor/<note>.mp3 c4..c7 + sharps (37 files)\n * tanpura/<pc>.mp3 12 pitch classes (c, cs, d, …)\n * tabla/<seg>/<seg><bpm>bpm.mp3 seg = <taal>[-<variation>], bpm 60..300 step 15\n * metronome/metro2.mp3\n */\n// Import TAALS from the taals subpath (not the ../spec/index barrel): the\n// barrel re-exports schema.ts, which statically imports zod — pulling that into\n// the player would break its \"loads bare in a browser\" guarantee. taals.ts has\n// only a type-only schema import, so this keeps the player runtime zod-free.\nimport type { Taal } from '../spec/schema.js';\nimport { TAALS, type TaalId } from '../spec/taals.js';\nimport { sCurve, sampleFileName } from './pitch.js';\n\n/** The dynamically-imported Tone module, typed without importing it. */\nexport type ToneModule = typeof import('tone');\n\n/** A melodic instrument: a Tone.Sampler note→filename map + where to find it. */\nexport interface InstrumentDef {\n /** Human label for UIs. */\n label: string;\n /** Tone.Sampler `urls`: note name (`C#4`) → filename (`Cs4.mp3`). */\n urls: Record<string, string>;\n /** Sample directory: an absolute URL, or — when `local` — a path segment\n * appended to the player's `soundsBaseUrl`. */\n baseUrl: string;\n /** `baseUrl` is relative to `soundsBaseUrl` (needs it set). */\n local?: boolean;\n /** Sampler release time in seconds. */\n release?: number;\n}\n\n/** Built-in melody instrument ids (consumers may add their own via the\n * player's `customInstruments`, so the runtime id type stays open). */\nexport type InstrumentId = string;\n\n/**\n * Default host for the project's samples (santoor / tabla / tanpura /\n * metronome) — CORS-enabled, so the player works with zero config. Override via\n * the player's `soundsBaseUrl` to self-host. (Melody defaults to the CDN-hosted\n * piano, so it needs no host.) Licences: see THIRD-PARTY.md.\n */\nexport const DEFAULT_SOUNDS_BASE = 'https://bitoron.pages.dev/audio/instruments/';\n/** CC-BY Salamander Grand Piano (Tone's de-facto piano), CDN-hosted. */\nexport const SALAMANDER_BASE = 'https://tonejs.github.io/audio/salamander/';\n/** CC-BY tonejs-instruments sample CDN (harmonium/violin/flute). */\nexport const TONEJS_INSTRUMENTS_BASE = 'https://nbrosowsky.github.io/tonejs-instruments/samples/';\n\n/** Build a Tone.Sampler `urls` map from bare note keys (`C#4` → `Cs4.mp3`). */\nfunction keyMap(keys: readonly string[]): Record<string, string> {\n const m: Record<string, string> = {};\n for (const k of keys) m[k] = `${k.replace('#', 's')}.mp3`;\n return m;\n}\n\nconst PIANO_KEYS = [\n 'A0', 'C1', 'D#1', 'F#1', 'A1', 'C2', 'D#2', 'F#2', 'A2', 'C3', 'D#3', 'F#3',\n 'A3', 'C4', 'D#4', 'F#4', 'A4', 'C5', 'D#5', 'F#5', 'A5', 'C6', 'D#6', 'F#6',\n 'A6', 'C7', 'D#7', 'F#7', 'A7', 'C8',\n] as const;\n// harmonium — a core Rabindrasangeet accompaniment (C2..C5). The CDN set has no F#4 (404).\nconst HARMONIUM_KEYS = [\n 'C2', 'C#2', 'D2', 'D#2', 'E2', 'F2', 'F#2', 'G2', 'G#2', 'A2', 'A#2',\n 'C3', 'C#3', 'D3', 'D#3', 'E3', 'F3', 'F#3', 'G3', 'G#3', 'A3', 'A#3',\n 'C4', 'C#4', 'D4', 'D#4', 'E4', 'F4', 'G4', 'G#4', 'A4', 'A#4',\n 'C5', 'C#5', 'D5',\n] as const;\nconst VIOLIN_KEYS = ['A3', 'C4', 'E4', 'G4', 'A4', 'C5', 'E5', 'G5', 'A5', 'C6', 'E6', 'G6', 'A6', 'C7'] as const;\nconst FLUTE_KEYS = ['C4', 'E4', 'A4', 'C5', 'E5', 'A5', 'C6', 'E6', 'A6', 'C7'] as const;\n\n/** Built-in melody instruments. santoor is local; the rest are CDN-hosted\n * (CC-BY) so they need only network — `pianoBaseUrl`/`customInstruments`\n * override for self-hosting. */\nexport const INSTRUMENTS: Record<string, InstrumentDef> = {\n piano: { label: 'Grand piano', urls: keyMap(PIANO_KEYS), baseUrl: SALAMANDER_BASE, release: 1 },\n santoor: { label: 'Santoor', urls: santoorUrls(), baseUrl: 'santoor/', local: true, release: 1.2 },\n harmonium: { label: 'Harmonium', urls: keyMap(HARMONIUM_KEYS), baseUrl: `${TONEJS_INSTRUMENTS_BASE}harmonium/`, release: 1.4 },\n violin: { label: 'Violin', urls: keyMap(VIOLIN_KEYS), baseUrl: `${TONEJS_INSTRUMENTS_BASE}violin/`, release: 1 },\n flute: { label: 'Flute', urls: keyMap(FLUTE_KEYS), baseUrl: `${TONEJS_INSTRUMENTS_BASE}flute/`, release: 1 },\n};\n\n/** Taals with recorded tabla loops (everything else → metronome fallback). */\nexport const SAMPLED_TAALS: ReadonlySet<TaalId> = new Set(\n Object.keys(TAALS) as TaalId[],\n);\n\n/** Available tabla loop tempos (file suffix `…<bpm>bpm.mp3`). */\nexport const TABLA_BPMS: readonly number[] = Array.from({ length: 17 }, (_, i) => 60 + i * 15);\n\n/**\n * Tabla loop variations per taal. Most taals have one unnamed loop at\n * `tabla/<id>/`; an entry here overrides that:\n * - `variations` lists the variation suffixes, **first = default**.\n * A lone named variation (shashthi → `pro`, i.e. `tabla/shashthi-pro/`) IS\n * the default; later entries are premium upsells the player never auto-selects.\n * An empty-string entry (kehrwa → `''`) means the unnamed `tabla/<id>/` loop\n * is the default and a named entry follows it as an upsell.\n * - `skipBpms` are grid tempos this taal's loops were not recorded at.\n * Consumers read this to build a variation/upsell UI; the player itself only\n * ever plays the default (or whatever a doc's `meta.taal.variation` pins).\n */\nexport const TABLA_VARIATIONS: Record<\n string,\n { variations: string[]; skipBpms?: number[] }\n> = {\n // ষষ্ঠী loops live under `tabla/shashthi-pro/`; full bpm grid recorded except 225.\n shashthi: { variations: ['pro'], skipBpms: [225] },\n // Kehrwa keeps its unnamed default loop; `qawwali` (tabla/kehrwa-qawwali/) is a\n // premium upsell variation recorded 90–300 (no 60/75).\n // ponytail: skipBpms is per-taal, so it can't restrict qawwali's 60/75 without\n // also dropping them from the default (which has them) — a qawwali doc pinned\n // ≤67 bpm 404s harmlessly. Make skipBpms per-variation only if that edge bites.\n kehrwa: { variations: ['', 'qawwali'] },\n};\n\n/** Tabla tempos actually available for a taal: the grid minus any it lacks. */\nexport function tablaBpms(taalId: string): readonly number[] {\n const skip = TABLA_VARIATIONS[taalId]?.skipBpms;\n return skip && skip.length ? TABLA_BPMS.filter((b) => !skip.includes(b)) : TABLA_BPMS;\n}\n\n/** CDN directory/filename segment for a taal's tabla loop: `<taalId>` or\n * `<taalId>-<variation>` (explicit variation, else the taal's default). */\nfunction tablaSeg(taalId: string, variation?: string): string {\n const v = variation ?? TABLA_VARIATIONS[taalId]?.variations[0]; // default = first variation, else unnamed\n return v ? `${taalId}-${v}` : taalId;\n}\n\n/** Ensure exactly one trailing slash. */\nexport function normalizeBase(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\n/** The 37 santoor samples, as a Tone.Sampler `urls` map (`C4` → `c4.mp3`). */\nexport function santoorUrls(): Record<string, string> {\n const urls: Record<string, string> = {};\n const add = (midi: number) => {\n const stem = sampleFileName(midi); // e.g. cs4\n const name = stem.replace('s', '#').replace(/^(.)/, (c) => c.toUpperCase()); // C#4\n urls[name] = `${stem}.mp3`;\n };\n for (let midi = 60; midi <= 95; midi++) add(midi); // C4..B6 (full)\n add(96); // C7\n return urls;\n}\n\nconst PC_BASE: Record<string, number> = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 };\n\n/** Parse a sample note name (`C#4`, `Ds3`, `Bb2`) to a MIDI number. */\nexport function noteToMidi(name: string): number {\n const m = /^([a-g])([#sb]?)(-?\\d+)$/i.exec(name.trim());\n if (!m) return NaN;\n const base = PC_BASE[m[1]!.toLowerCase()]!;\n const acc = m[2] === 'b' ? -1 : m[2] === '' ? 0 : 1; // # / s → sharp\n return (Number(m[3]) + 1) * 12 + base + acc;\n}\n\n/**\n * Restrict a Sampler `urls` map to just the samples needed to cover MIDI\n * `[lo, hi]`: every sample inside the range, plus the nearest one below and\n * above it (so Tone interpolates the edges without extrapolating). Cuts a\n * typical song from ~37 santoor files to a handful — a big win on mobile and\n * never worse on fast links (Tone fetches what's left in parallel). The\n * Sampler pitch-shifts from the nearest sample, so audio is unchanged.\n */\nexport function subsetUrls(\n urls: Record<string, string>,\n lo: number,\n hi: number,\n): Record<string, string> {\n const entries = Object.entries(urls)\n .map(([k, f]) => ({ k, f, midi: noteToMidi(k) }))\n .filter((e) => Number.isFinite(e.midi))\n .sort((a, b) => a.midi - b.midi);\n if (entries.length === 0) return { ...urls };\n\n const keep = new Set<string>();\n for (const e of entries) if (e.midi >= lo && e.midi <= hi) keep.add(e.k);\n // nearest sample at/below lo and at/above hi for clean interpolation\n let floor: string | undefined;\n let ceil: string | undefined;\n for (const e of entries) if (e.midi <= lo) floor = e.k;\n for (const e of entries) if (e.midi >= hi) { ceil = e.k; break; }\n if (floor) keep.add(floor);\n if (ceil) keep.add(ceil);\n if (keep.size === 0) {\n // range entirely outside the sample set — keep the single nearest sample\n const mid = (lo + hi) / 2;\n const nearest = entries.reduce((a, b) => (Math.abs(b.midi - mid) < Math.abs(a.midi - mid) ? b : a));\n keep.add(nearest.k);\n }\n\n const out: Record<string, string> = {};\n for (const e of entries) if (keep.has(e.k)) out[e.k] = e.f;\n return out;\n}\n\n/** Resolve a representative sample URL for an instrument (its first sample),\n * used to probe availability. undefined when a local instrument has no\n * `soundsBaseUrl` or the def has no samples. */\nexport function instrumentSampleUrl(def: InstrumentDef, soundsBaseUrl?: string): string | undefined {\n if (def.local && soundsBaseUrl === undefined) return undefined;\n const base = def.local ? `${normalizeBase(soundsBaseUrl ?? '')}${def.baseUrl}` : def.baseUrl;\n const file = Object.values(def.urls)[0];\n return file === undefined ? undefined : `${normalizeBase(base)}${file}`;\n}\n\n/**\n * Liveness check for a sample URL: a single tiny ranged GET (one byte), the\n * same CORS-enabled fetch Tone uses to load the buffer — so a pass means Tone\n * can actually load it. Resolves false on any error/timeout/non-2xx, and false\n * (no throw) when `fetch` is unavailable (Node/SSR). `Range: bytes=0-0` is a\n * CORS-safelisted header, so no preflight.\n */\nexport async function probeUrl(url: string, timeoutMs = 6000): Promise<boolean> {\n if (typeof fetch === 'undefined') return false;\n const ctrl = typeof AbortController !== 'undefined' ? new AbortController() : undefined;\n const timer = ctrl ? setTimeout(() => ctrl.abort(), timeoutMs) : undefined;\n try {\n const res = await fetch(url, {\n method: 'GET',\n headers: { Range: 'bytes=0-0' },\n cache: 'no-store',\n signal: ctrl?.signal,\n });\n return res.ok; // 200 / 206\n } catch {\n return false;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\n/**\n * Snap a tabla loop's end to the nearest whole beat of its measured length so a\n * slightly-mistrimmed file still phase-locks to the melody grid instead of\n * drifting a fraction of a beat each cycle. `spb` = seconds per beat (60/bpm).\n * No-op for correctly trimmed loops (already an integer beat count); never\n * extends past the buffer — a too-short file can't be repaired here.\n *\n * ponytail: belt-and-braces for off-spec audio; the real fix is trimming each\n * loop to exactly `cycles × numBeats × 60/bpm` seconds at production time.\n */\nexport function quantizeLoopEnd(durationSec: number, spb: number): number {\n if (spb <= 0) return durationSec;\n const beats = Math.round(durationSec / spb);\n if (beats < 1) return durationSec; // too short to snap to a beat\n return Math.min(beats * spb, durationSec);\n}\n\n/** Snap an arbitrary bpm to the nearest available tabla tempo (default grid;\n * pass a taal's `tablaBpms()` so it never snaps to a tempo that taal lacks). */\nexport function nearestTablaBpm(bpm: number, bpms: readonly number[] = TABLA_BPMS): number {\n return bpms.reduce((best, b) => (Math.abs(b - bpm) < Math.abs(best - bpm) ? b : best), bpms[0]!);\n}\n\n/** URL of the tabla loop for a taal at a (snapped) bpm, optionally a named\n * variation (defaults to the taal's default variation — see TABLA_VARIATIONS). */\nexport function tablaUrl(base: string, taalId: string, bpm: number, variation?: string): string {\n const seg = tablaSeg(taalId, variation);\n return `${normalizeBase(base)}tabla/${seg}/${seg}${bpm}bpm.mp3`;\n}\n\n/**\n * Pitch class (0 = C) the tabla loops were recorded at: their dayan (the tuned\n * right drum) rings at Sa ≈ C — measured off the CDN loops themselves\n * (spectral peak of the stroke decays, ~529 Hz = C5 +20 cents, consistent\n * across taals and across every bpm variant, i.e. the tempo set was\n * time-stretched, not resampled). Calibration knob: re-measure and change this\n * if the loop set is ever re-recorded.\n */\nexport const TABLA_TONIC_SEMITONE = 0;\n\n/**\n * Semitones to pitch-shift a tabla loop so its dayan matches the song's Sa.\n * Wrapped to the nearer direction (−5…+6): the drum is octave-agnostic, so a\n * B tonic shifts down 1 rather than up 11.\n */\nexport function tablaShiftSemitones(tonicSemitone: number): number {\n const d = (((tonicSemitone - TABLA_TONIC_SEMITONE) % 12) + 12) % 12;\n return d > 6 ? d - 12 : d;\n}\n\n/**\n * Grain settings for a retuned tabla loop (`Tone.GrainPlayer`, which detunes\n * independently of playback rate — so the loop keeps its recorded tempo and\n * stays phase-locked).\n *\n * Why not `Tone.PitchShift` after a plain `Player`: measured offline on the\n * teentaal loop, both shift accurately (±2 and −5 semitones confirmed by\n * spectral cross-correlation), but PitchShift's delay lines push the first\n * stroke 20–35 ms late (audibly behind the melody) and smear the spectrum;\n * GrainPlayer holds the onset at ~4 ms. Grains short enough not to blur the\n * strokes, overlapped half-way so the loop stays seamless.\n */\nexport const TABLA_GRAIN_SEC = 0.06;\nexport const TABLA_GRAIN_OVERLAP_SEC = 0.03;\n\n/** URL of the metronome click. */\nexport function metronomeUrl(base: string): string {\n return `${normalizeBase(base)}metronome/metro2.mp3`;\n}\n\n/** Build the metronome click `Tone.Player`. */\nexport function createMetronome(Tone: ToneModule, base: string) {\n return new Tone.Player(metronomeUrl(base));\n}\n\n/** Tanpura pitch-class sample stems (filename = `<stem>.mp3`). */\nexport const TANPURA_PCS = ['c', 'cs', 'd', 'ds', 'e', 'f', 'fs', 'g', 'gs', 'a', 'as', 'b'] as const;\n\n/* ---- Drum kit (Western-drumset rendering of an Indian taal) ------------\n *\n * A real drumset \"translation\" of tabla bols is an established practice\n * (e.g. Sunny Jain's Drum Atlas: India — kick on sam, snare on the accented\n * tali claps, hi-hat filling/ghosting the khaali wave), not something\n * invented here. DRUM_VOICES are one-shot acoustic-kit samples (CC0-cleared\n * Apache-2.0 Tonejs/audio collection, https://github.com/Tonejs/audio,\n * already the CDN this project uses directly for the Salamander piano) —\n * same trust tier as the other CDN-hosted instruments, no new hosting.\n */\nexport const DRUM_KIT_BASE = 'https://tonejs.github.io/audio/drum-samples/acoustic-kit/';\n\nexport type DrumVoice = 'kick' | 'snare' | 'hihat' | 'tom1' | 'tom2' | 'tom3';\nconst DRUM_FILES: Record<DrumVoice, string> = {\n kick: 'kick.mp3',\n snare: 'snare.mp3',\n hihat: 'hihat.mp3',\n tom1: 'tom1.mp3',\n tom2: 'tom2.mp3',\n tom3: 'tom3.mp3',\n};\n\n/** Build the drum-kit `Tone.Players` (one-shot voices, not looped/pitched). */\nexport function createDrumKit(Tone: ToneModule, base: string = DRUM_KIT_BASE) {\n const urls: Record<string, string> = {};\n for (const [voice, file] of Object.entries(DRUM_FILES)) urls[voice] = file;\n return new Tone.Players({ urls, baseUrl: normalizeBase(base) });\n}\n\n/**\n * Per-beat drumset voice for one তাল cycle, following sam/tali/khaali theory:\n * sam (cycle start) → kick, the first beat of each accented (non-khaali)\n * vibhag → snare (the tali clap), the first beat of a khaali vibhag → closed\n * hihat (the khaali \"wave off\"), every other beat → hihat (fill, keeping the\n * kit's groove going the way a tabla's filler strokes do).\n */\nexport function drumPattern(taal: Pick<Taal, 'numBeats' | 'sam' | 'bhaags' | 'khaali'>): DrumVoice[] {\n const n = taal.numBeats;\n const sam = taal.sam ?? 0;\n const khaali = new Set(taal.khaali ?? []);\n const bhaags = taal.bhaags ?? [n];\n const pattern: DrumVoice[] = new Array(n).fill('hihat');\n\n let pos = 0;\n for (const len of bhaags) {\n pattern[pos] = khaali.has(pos) ? 'hihat' : 'snare';\n pos += len;\n }\n pattern[sam] = 'kick';\n return pattern;\n}\n\n/**\n * Build a melody `Tone.Sampler` for an instrument def. Resolves the sample\n * directory (local → under `soundsBaseUrl`, else the def's absolute CDN URL)\n * and, when a MIDI `range` is given, loads only the samples that cover it.\n */\nexport function createSampler(\n Tone: ToneModule,\n def: InstrumentDef,\n soundsBaseUrl: string | undefined,\n range?: { lo: number; hi: number },\n) {\n const base = def.local ? `${normalizeBase(soundsBaseUrl ?? '')}${def.baseUrl}` : def.baseUrl;\n const urls = range ? subsetUrls(def.urls, range.lo, range.hi) : def.urls;\n return new Tone.Sampler({ urls, baseUrl: normalizeBase(base), release: def.release ?? 1 });\n}\n\n/* ---- মীড় (meend) — the sounded glide -------------------------------------\n *\n * A মীড় is one continuous sound whose pitch travels between svaras; the notes\n * it covers are never re-struck. A `Tone.Sampler` cannot do that — it has no\n * pitch parameter at all (checked against tone 15's own typings). What it does\n * have, one layer down, is `ToneBufferSource.playbackRate`, a real AudioParam:\n * so a glide is the instrument's own sample, started once, with its playback\n * rate automated — a tape slide, which is exactly what a hardware sampler does\n * for portamento.\n *\n * The pitch is automated as an S-curve (see `sCurve`), not a straight line, and\n * it leaves the source svara only after `MEEND_HOLD` of the gap so the written\n * note keeps its identity before rolling into the next — arriving exactly on\n * the target's own matra.\n *\n * ponytail: the glide reads from a second `ToneAudioBuffers` over the same\n * URLs as the Sampler (the browser HTTP cache means no extra download, just a\n * second decode). Share one buffer set if memory ever matters.\n */\n\n/**\n * Fraction of the gap between two মীড় notes spent holding the source pitch\n * before the slide begins. 0 = slide the whole way (an alaap-slow meend);\n * 0.5 = hold half the note, then roll into the target.\n */\nexport const MEEND_HOLD = 0.5;\n\n/** Automation points per glide leg — enough to hear as continuous. */\nconst GLIDE_STEPS = 24;\n\n/** Sampler `urls` key whose pitch is nearest `midi` (the sample to slide). */\nexport function nearestSampleKey(urls: Record<string, string>, midi: number): string {\n let best = '';\n let bestDiff = Infinity;\n for (const key of Object.keys(urls)) {\n const diff = Math.abs(noteToMidi(key) - midi);\n if (diff < bestDiff) {\n bestDiff = diff;\n best = key;\n }\n }\n return best;\n}\n\n/** The same samples `createSampler` loads, as raw buffers for the glide voice. */\nexport function createBuffers(\n Tone: ToneModule,\n def: InstrumentDef,\n soundsBaseUrl: string | undefined,\n range?: { lo: number; hi: number },\n) {\n const base = def.local ? `${normalizeBase(soundsBaseUrl ?? '')}${def.baseUrl}` : def.baseUrl;\n const urls = range ? subsetUrls(def.urls, range.lo, range.hi) : def.urls;\n return { buffers: new Tone.ToneAudioBuffers({ urls, baseUrl: normalizeBase(base) }), urls };\n}\n\n/** One মীড় leg: the pitch to reach and the absolute time to reach it by. */\nexport interface GlideLeg {\n midi: number;\n /** Seconds on the transport; `legs[0]` is the attack itself. */\n at: number;\n}\n\n/**\n * Sound one মীড় phrase: a single attack on `legs[0]` whose pitch then slides\n * through every following leg, ending at `endSec`. Used by both the live\n * player and the offline export.\n */\nexport function triggerGlide(\n Tone: ToneModule,\n buffers: InstanceType<ToneModule['ToneAudioBuffers']>,\n urls: Record<string, string>,\n dest: InstanceType<ToneModule['Gain']>,\n legs: readonly GlideLeg[],\n endSec: number,\n release = 1,\n hold = MEEND_HOLD,\n): void {\n const key = nearestSampleKey(urls, legs[0]!.midi);\n if (key === '' || !buffers.has(key)) return;\n const sampleMidi = noteToMidi(key);\n const rate = (midi: number) => Math.pow(2, (midi - sampleMidi) / 12);\n\n const source = new Tone.ToneBufferSource({\n url: buffers.get(key),\n fadeOut: release,\n curve: 'exponential',\n // Bind to the destination's context explicitly. `Tone.Offline` restores the\n // global context the moment it starts rendering, so a node built inside a\n // transport callback would otherwise land on the *online* context and the\n // offline export would render the glide as silence.\n context: dest.context,\n }).connect(dest);\n // Clean up after the note — but only on a live context. An offline render\n // runs its whole clock *before* `startRendering()`, so an onended-dispose\n // would disconnect the node before a single sample was rendered (the export\n // came out silent). The offline context is discarded wholesale anyway.\n if (!dest.context.isOffline) source.onended = () => source.dispose();\n\n const rates = source.playbackRate;\n rates.setValueAtTime(rate(legs[0]!.midi), legs[0]!.at);\n for (let k = 1; k < legs.length; k++) {\n const from = legs[k - 1]!;\n const to = legs[k]!;\n const start = from.at + (to.at - from.at) * hold;\n const values: number[] = [];\n for (let n = 0; n <= GLIDE_STEPS; n++) {\n values.push(rate(from.midi + (to.midi - from.midi) * sCurve(n / GLIDE_STEPS)));\n }\n rates.setValueCurveAtTime(values, start, Math.max(to.at - start, 0.02));\n }\n source.start(legs[0]!.at, 0, Math.max(endSec - legs[0]!.at, 0.05));\n}\n\n/** Build a tanpura `Tone.Players` loading only the given pitch-class stems\n * (the drone only ever plays Sa + Pa, so we fetch 2 files, not 12). */\nexport function createTanpura(Tone: ToneModule, base: string, stems: readonly string[] = TANPURA_PCS) {\n const urls: Record<string, string> = {};\n for (const s of stems) urls[s] = `${s}.mp3`;\n return new Tone.Players({ urls, baseUrl: `${normalizeBase(base)}tanpura/` });\n}\n","/**\n * `SwaralipiPlayer` — the stateful audio facade over Tone.js.\n *\n * Tone is **dynamically imported** on first `play()` so that importing\n * `@ugfoundation/swaralipi-js/player` in Node/SSR (or just to reach the pure\n * helpers) never pulls in the audio engine or touches `AudioContext`. The\n * pure cores (pitch.ts, schedule.ts, instruments.ts) carry the logic; this\n * class only wires them onto the Tone Transport and drives the viewer's\n * `highlight()`.\n *\n * Model: build a beat-timed `Schedule`, lay each note onto the Transport in\n * seconds (`beat × 60/bpm`), loop a tabla (or click a metronome) underneath,\n * drone a tanpura, and fire highlights on Tone's draw thread. Practice rides\n * the same Transport: a seek moves its position, a repeated line is its loop,\n * and the notes are persistent events so each pass plays them again. A\n * setting change while playing re-arranges from the current note (no\n * mid-stream tempo ramp).\n */\nimport type { Gain, GrainPlayer, Players, Player, Sampler, ToneAudioBuffers, Unit } from 'tone';\nimport type { Swaralipi } from '../spec/index.js';\n// Taal type-only from schema.ts (not the barrel) — keeps the player zod-free,\n// same reason instruments.ts imports TAALS from the taals subpath.\nimport type { Taal } from '../spec/schema.js';\n// TAALS from the taals subpath, not the barrel — see the note in instruments.ts\n// (the barrel pulls zod, which would defeat the player's bare-load guarantee).\nimport { TAALS, type TaalId } from '../spec/taals.js';\nimport type { LaySpeeds } from '../spec/lay.js';\nimport type { Excerpt } from './lyrics.js';\nimport { midiToSampleName, parseTonic } from './pitch.js';\nimport {\n GRACE_STEP,\n buildSchedule,\n byRow,\n eventAt,\n glideTargets,\n graceTouches,\n lineAt,\n lineFor,\n scheduleLines,\n type Line,\n type Schedule,\n type TempoSegment,\n} from './schedule.js';\nimport {\n DEFAULT_SOUNDS_BASE,\n INSTRUMENTS,\n SAMPLED_TAALS,\n TABLA_GRAIN_OVERLAP_SEC,\n TABLA_GRAIN_SEC,\n TANPURA_PCS,\n createDrumKit,\n createBuffers,\n createMetronome,\n createSampler,\n createTanpura,\n drumPattern,\n instrumentSampleUrl,\n nearestTablaBpm,\n normalizeBase,\n probeUrl,\n quantizeLoopEnd,\n tablaBpms,\n triggerGlide,\n tablaShiftSemitones,\n tablaUrl,\n type InstrumentDef,\n type InstrumentId,\n type ToneModule,\n} from './instruments.js';\n\n/** Seconds the accompaniment fades over when playback is stopped. */\nconst STOP_FADE_SEC = 0.5;\n\n/**\n * How long the outgoing tabla loop rings on under the incoming one at a লয়\n * or তাল change. The new loop starts clean on the boundary (which is a সম), so\n * this only lets the previous stroke decay instead of being cut mid-skin — the\n * transition a tabla player actually makes when the laya or taal turns over.\n */\nconst LAY_TAIL_SEC = 0.12;\n\n/**\n * How far before its target a start or a seek puts the transport. Tone 15.5\n * skips the tick a clock *starts* on whenever float error lands it a hair\n * early (its \"advance past ticks before this window\" guard), and whatever sat\n * on that tick was lost: measured, 2 in 25 fresh plays dropped their first\n * note and never started the tabla (whose synced start is also a tick-0\n * event). Starting a couple of ticks early leaves that tick empty. At least\n * two ticks at 40 bpm, and far under the 0.1 s a tap can take to feel instant.\n */\nconst START_PREROLL_SEC = 0.02;\n\n/** Taal mode has no document and so no লয়: one open-ended segment at the\n * requested tempo. */\nconst TAAL_MODE_TEMPO: readonly TempoSegment[] = [\n { beat: 0, endBeat: Infinity, scale: 1, lay: 'drut' },\n];\n\n/**\n * How far ahead of its note `onEvent` is fired, on top of the transport's own\n * lookahead. It exists for one consumer: OS media-session metadata (a lock\n * screen's lyric line), where the write still has to cross into the system's\n * Now Playing store and wait for that surface to repaint — iOS refreshes an\n * Always-On display only about once a second, by design (Apple DTS,\n * developer.apple.com/forums/thread/812421) — so a write that lands after the\n * note is not seen until the next refresh. Leading it cannot make the line\n * late, only early, and an early lock-screen line reads as a cue. Capped at one\n * matra at the call site so a fast tempo can't run a whole beat ahead.\n *\n * ponytail: no web API can measure the OS's own latency, so this is a\n * calibration knob, not a measurement — retune it against a device.\n */\nconst MEDIA_LEAD_SEC = 0.25;\n\nexport type PlayerState = 'idle' | 'loading' | 'ready' | 'playing' | 'paused';\nexport type RhythmMode = 'tabla' | 'drums' | 'metronome' | 'none';\n\n/** Repeated lines, as `part.row` paths (the viewer's `data-row`), inclusive. */\nexport interface LineRange {\n from: string;\n to: string;\n}\n\n/** What the practice controls show: the repeated lines, whether the learner\n * sings each pass back, and whether the pass now sounding is theirs. */\nexport interface PracticeState {\n loop: LineRange | null;\n echo: boolean;\n yourTurn: boolean;\n}\n\nexport interface PlayerOptions {\n /** Base URL for the project's samples (santoor/tabla/tanpura/metronome).\n * Defaults to `DEFAULT_SOUNDS_BASE` (the project's CORS-enabled CDN), so the\n * player works with zero config; override to self-host. */\n soundsBaseUrl?: string;\n /** Grand-piano sample host. Default: the Salamander CDN (see SALAMANDER_BASE).\n * Set this to self-host the piano under your own URL. */\n pianoBaseUrl?: string;\n /** Tonic (Sa). Accepts `C`, `C#`, `cs`… Default: doc tonic, else `C`. */\n tonic?: string;\n /** Tempo in matra/min — the **দ্রুত** (fast) tempo; লয় marks scale down from\n * it. Default 90. Snapped to the 15-grid while tabla plays. */\n bpm?: number;\n /** Override the লয় tempo factors, e.g. `{ vilambit: 0.6 }`. Defaults come\n * from the document's `meta.laySpeeds`, else `LAY_SPEEDS` (drut 1, madhya\n * 0.75, vilambit 0.5). */\n laySpeeds?: LaySpeeds;\n /** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */\n baseOctave?: number;\n /** Active melody instrument id (a built-in or a `customInstruments` key).\n * Default `piano` (CDN-hosted, zero-config). Built-ins: piano, santoor,\n * harmonium, violin, flute. */\n instrument?: InstrumentId;\n /** Instrument ids the UI may expose. Default: all built-ins. Narrow it to\n * e.g. `['santoor','harmonium']` to limit the picker. */\n instruments?: InstrumentId[];\n /** Extra melody instruments, keyed by id — e.g. a self-hosted sitar/sarod.\n * (True sampled sitar/sarod/sarangi/esraj have no free web set; supply your\n * own Tone.Sampler `urls` + `baseUrl` here and they slot into the picker.) */\n customInstruments?: Record<string, InstrumentDef>;\n /** Rhythm accompaniment. Default `tabla` (→ metronome for unsampled taals).\n * `drums` sequences a Western drumset (kick/snare/hihat) to the taal's\n * sam/tali/khaali structure — a genuine \"drum atlas\"-style translation,\n * not a loop; works for every taal (no per-taal sample requirement). */\n rhythm?: RhythmMode;\n /** Play the tanpura drone. Default true. */\n tanpura?: boolean;\n /** Sing the song's form: each `{ }` twice, `( )` only the first time, the\n * `[ ]` notes on the repeat, and back to the asthayi at each kali's end\n * (when a ‖ says where to stop). Default true; false plays it as written. */\n repeats?: boolean;\n /** Stop playback after this many seconds (a policy-neutral preview cap).\n * Default `Infinity` (unlimited). The library only enforces the number it is\n * handed; who is capped / the value / the upsell is the consumer's policy. */\n previewLimitSec?: number;\n /** Called when the preview cap stops playback (so the consumer can show an\n * upsell). Not called on a normal stop()/end. */\n onLimit?: () => void;\n /** Called with the active note's `part.row.note` path, or null when idle.\n * `yourTurn` is true while the melody is silent for the learner to sing\n * (see `setEcho`): the note is where they should be, not what is sounding. */\n onHighlight?: (path: string | null, yourTurn?: boolean) => void;\n /** Called whenever the repeat, the sing-back or the learner's turn changes. */\n onLoop?: (state: PracticeState) => void;\n /** The same path, but fired on the AUDIO clock — Tone's worker ticker, the one\n * that fires the notes themselves — so it keeps arriving while the page is\n * hidden. `onHighlight` cannot: it runs on Tone.Draw, i.e.\n * `requestAnimationFrame`, which stops the moment a screen locks, so anything\n * hanging off it freezes until the reader looks at the page again. Use this for\n * consumers that are not drawing (media-session metadata, analytics); it fires\n * early — one transport lookahead (~0.1s) plus MEDIA_LEAD_SEC — and only in\n * doc mode. */\n onEvent?: (path: string | null) => void;\n /** Taal mode only (`loadTaal`): called on the draw thread once per matra with\n * the beat index within the cycle (0-based, `< numBeats`), so a consumer can\n * highlight the active theka bol / drum-staff note. Never fired in doc mode. */\n onBeat?: (beatInCycle: number) => void;\n /** Called on every state transition. */\n onState?: (state: PlayerState) => void;\n}\n\n/** Minimal shape of the viewer element the player drives (avoids a hard\n * dependency on the viewer module). `highlight` returns the highlighted node\n * (or null) so bindSheet can optionally scroll it into view. */\ninterface HighlightTarget {\n highlight(path: string, yourTurn?: boolean): HTMLElement | null;\n clearHighlights(): void;\n /** Shade the repeated lines, and mark the learner's turn on them. */\n markLoop?(loop: LineRange | null, yourTurn: boolean): void;\n}\n\n/** The `<swaralipi-sheet>` tap event: play from `path`, or with Shift,\n * stretch the repeat to its line. */\ntype SeekEvent = CustomEvent<{ path: string; extend: boolean }>;\n\n/**\n * A GrainPlayer that survives a seek. When the transport jumps (a tap-to-play,\n * a repeat wrapping), Tone restarts a synced source with its offset in\n * transport seconds — but a loop stretched to `playbackRate` has only played\n * rate × that much of its buffer, so a stretched tabla came back out of phase\n * (Tone.js issue #349, still open in 15.1).\n */\nconst seekableGrain = (Tone: ToneModule) =>\n class extends Tone.GrainPlayer {\n protected override _start(time?: Unit.Time, offset?: Unit.Time, duration?: Unit.Time): void {\n super._start(time, offset === undefined ? offset : this.toSeconds(offset) * this.playbackRate, duration);\n }\n };\n\n/** MIDI span (incl. কণ/রেশ graces) of a schedule's notes, for sample subsetting;\n * undefined when there are no pitched events. */\nfunction midiRange(schedule: Schedule): { lo: number; hi: number } | undefined {\n let lo = Infinity;\n let hi = -Infinity;\n for (const ev of schedule.events) {\n for (const m of [ev.midi, ...ev.kan, ...ev.resh]) {\n if (m !== null) {\n if (m < lo) lo = m;\n if (m > hi) hi = m;\n }\n }\n }\n return lo <= hi ? { lo, hi } : undefined;\n}\n\n/**\n * Wall-clock length of one play-through — the moment `#arrange` schedules the\n * auto-stop, so a progress bar built on it hits 100% exactly when the player\n * stops. The trailing `+ spb` is the matra the last note rings into; the pickup\n * shift only counts when a rhythm actually loops underneath (see #arrange).\n */\nfunction playDurationSec(schedule: Schedule, spb: number, rhythm: RhythmMode): number {\n return schedule.totalBeats * spb + (rhythm !== 'none' ? schedule.pickupBeats * spb : 0) + spb;\n}\n\n/**\n * Wait for sample buffers, but never let one bad URL strand playback.\n * `Tone.loaded()` rejects as soon as any buffer fails, so an unreachable\n * accompaniment sample (CDN down, wrong `soundsBaseUrl`, a taal with no\n * recorded loop at that tempo) would otherwise leave `play()` hung in the\n * `loading` state with nothing sounding — including the melody, which loaded\n * fine. Warn and carry on: the voices that did load still play.\n */\nasync function loadedOrWarn(Tone: ToneModule): Promise<void> {\n try {\n await Tone.loaded();\n } catch (err) {\n console.warn('[swaralipi] some audio samples failed to load; continuing without them', err);\n }\n}\n\nexport interface BindSheetOptions {\n /** Keep the active note visible while playing by calling `scrollIntoView`\n * on it. `true` → `'center'` (keeps the note's lyric, rendered just below it,\n * on screen too); or pass an explicit block position (`'nearest'`, `'start'`,\n * …). Default off so it never fights a host that manages its own scrolling.\n * Works through the shadow boundary, so it scrolls the page, not just the\n * sheet. */\n autoScroll?: boolean | ScrollLogicalPosition;\n}\n\n/** The common melody-voice call the scheduler needs — both melody instruments\n * are `Tone.Sampler`s, but this keeps the call site decoupled from the class. */\ninterface MelodyVoice {\n triggerAttackRelease(note: string, duration: number, time: number): unknown;\n releaseAll(time?: number): unknown;\n}\n\nexport class SwaralipiPlayer {\n #opts: Required<\n Omit<\n PlayerOptions,\n | 'soundsBaseUrl'\n | 'pianoBaseUrl'\n | 'customInstruments'\n | 'onHighlight'\n | 'onLoop'\n | 'onEvent'\n | 'onBeat'\n | 'onState'\n | 'onLimit'\n | 'tonic'\n | 'bpm'\n | 'laySpeeds'\n >\n > & {\n soundsBaseUrl?: string;\n pianoBaseUrl?: string;\n customInstruments?: Record<string, InstrumentDef>;\n tonic?: string;\n laySpeeds?: LaySpeeds;\n /** Pinned constructor tempo: overrides meta.bpm, survives load(). */\n bpm?: number;\n onHighlight?: (path: string | null, yourTurn?: boolean) => void;\n onLoop?: (state: PracticeState) => void;\n onEvent?: (path: string | null) => void;\n onBeat?: (beatInCycle: number) => void;\n onState?: (state: PlayerState) => void;\n onLimit?: () => void;\n };\n /** Per-song setBpm tweak: beats meta.bpm but is cleared by the next load(). */\n #bpmTweak: number | undefined;\n #doc: Swaralipi | undefined;\n /** Play only these stretches of the song's text (see `load`). */\n #excerpt: Excerpt | undefined;\n /** Taal mode (`loadTaal`): loops one avartan of this taal's theka with no\n * melody. Mutually exclusive with `#doc`. */\n #taal: Taal | undefined;\n #state: PlayerState = 'idle';\n\n #tone: ToneModule | undefined;\n /** Master bus everything routes through, so stop() can fade it out. */\n #master: Gain | undefined;\n /** Cached melody samplers keyed by instrument id, with the MIDI range each\n * was loaded for (rebuilt when a song needs a wider range). */\n #samplers = new Map<string, { sampler: Sampler; lo: number; hi: number }>();\n /** Raw sample buffers for the মীড় glide voice, keyed like #samplers. */\n #glide = new Map<string, { buffers: ToneAudioBuffers; urls: Record<string, string>; lo: number; hi: number }>();\n #tanpura: Players | undefined;\n #tanpuraKey = '';\n #metronome: Player | undefined;\n /** The looping tabla — one loop per লয় segment, each a `GrainPlayer` when\n * the tonic needs retuning or the segment's tempo needs stretching.\n * `fileSpb` is the recorded loop's OWN beat length, which is the unit\n * `quantizeLoopEnd` must snap in (loop points are buffer time). */\n #tabla: { loop: Player | GrainPlayer; fileSpb: number }[] = [];\n #grain: ReturnType<typeof seekableGrain> | undefined;\n #drums: Players | undefined;\n #scheduleIds: number[] = [];\n #fadeTimer: ReturnType<typeof setTimeout> | undefined;\n\n /* Practice: where the playhead is, what repeats, whose turn it is. */\n /** The last note played or sought — what \"this line\" means to the controls. */\n #cursor: string | null = null;\n /** The cursor as an event index: which pass of a line sung more than once. */\n #at = -1;\n /** Where the next fresh play() starts (a seek made while stopped). */\n #startAt: number | null = null;\n #loop: LineRange | null = null;\n /** The repeat as line indices, the passes it holds. */\n #span: [number, number] | null = null;\n #echo = false;\n /** With echo on, every other pass is the learner's: the melody rests. */\n #turn = false;\n /** The arranged timeline, so a seek or a loop can be placed while playing. */\n #timeline: { schedule: Schedule; lines: Line[]; spb: number; shift: number } | undefined;\n /** Listeners on the bound sheet, removed on rebind. */\n #unbind: AbortController | undefined;\n #sheet: HighlightTarget | undefined;\n /** The bound sheet's highlight — beside, never instead of, the consumer's `onHighlight`. */\n #paint: ((path: string | null, yourTurn: boolean) => void) | undefined;\n /** Preview cap, counted in listening time so a seek or a loop can't dodge it. */\n #listened = 0;\n #listenedSince = 0;\n #limitId: number | undefined;\n\n constructor(options: PlayerOptions = {}) {\n this.#opts = {\n soundsBaseUrl: options.soundsBaseUrl ?? DEFAULT_SOUNDS_BASE,\n pianoBaseUrl: options.pianoBaseUrl,\n customInstruments: options.customInstruments,\n tonic: options.tonic,\n bpm: options.bpm,\n laySpeeds: options.laySpeeds,\n baseOctave: options.baseOctave ?? 4,\n instrument: options.instrument ?? 'piano',\n instruments: options.instruments ?? Object.keys(INSTRUMENTS),\n rhythm: options.rhythm ?? 'tabla',\n tanpura: options.tanpura ?? true,\n repeats: options.repeats ?? true,\n previewLimitSec: options.previewLimitSec ?? Infinity,\n onHighlight: options.onHighlight,\n onLoop: options.onLoop,\n onEvent: options.onEvent,\n onBeat: options.onBeat,\n onState: options.onState,\n onLimit: options.onLimit,\n };\n }\n\n /* ----------------------------------------------------------------- */\n /* Public getters */\n /* ----------------------------------------------------------------- */\n\n get state(): PlayerState {\n return this.#state;\n }\n get bpm(): number {\n return this.#bpmTweak ?? this.#opts.bpm ?? this.#doc?.meta.bpm ?? 90;\n }\n /** The preview cap in seconds (`Infinity` = unlimited). */\n get previewLimitSec(): number {\n return this.#opts.previewLimitSec;\n }\n get instrument(): InstrumentId {\n return this.#effectiveInstrument();\n }\n get instruments(): InstrumentId[] {\n return [...this.#opts.instruments];\n }\n /** The taal currently driving the rhythm (auto from the doc, or an override). */\n get taalId(): TaalId | undefined {\n return this.#taalId();\n }\n /** Whether the effective rhythm will actually be a sampled tabla. */\n get usesTabla(): boolean {\n const id = this.#taalId();\n return this.#opts.rhythm === 'tabla' && id !== undefined && SAMPLED_TAALS.has(id) && !!this.#opts.soundsBaseUrl;\n }\n\n /**\n * Length of one play-through in seconds, for a progress bar (the OS media\n * session's, typically). Derived from the loaded notation on every read and\n * never stored, because every input can move: re-engrave the document, drag\n * the tempo, switch the rhythm off, and this changes with it. `Infinity` in\n * taal mode (one avartan looping, no end — the value the Media Session spec\n * reserves for exactly that), 0 with nothing loaded, and clamped by a preview\n * cap when one is set, since that is when playback will really stop.\n */\n get durationSec(): number {\n if (this.#taal !== undefined) return Infinity;\n if (this.#doc === undefined) return 0;\n const full = playDurationSec(buildSchedule(this.#doc, this.#scheduleOpts()), 60 / this.#effectiveBpm(), this.#opts.rhythm);\n return Math.min(full, this.#opts.previewLimitSec);\n }\n\n /** Seconds played so far, off the Transport's own clock — so it holds while\n * paused, and reads 0 before the first play and after stop(). */\n get positionSec(): number {\n return Math.max(this.#tone?.getTransport().seconds ?? 0, 0); // ≥ 0 through the start pre-roll\n }\n\n /** The note last played or sought (`part.row.note`), or null. */\n get cursor(): string | null {\n return this.#cursor;\n }\n /** The repeated lines, or null. */\n get loop(): LineRange | null {\n return this.#loop && { ...this.#loop };\n }\n /** Whether each repeat is followed by a silent pass for the learner. */\n get echo(): boolean {\n return this.#echo;\n }\n\n /* ----------------------------------------------------------------- */\n /* Loading + transport control */\n /* ----------------------------------------------------------------- */\n\n /** Set the document to play. Stops any current playback. With `excerpt`,\n * only the notes singing those stretches of the song's text play, in order\n * (see `alignLyrics`); the length, seeks and repeats all keep to them. */\n load(doc: Swaralipi, { excerpt }: { excerpt?: Excerpt } = {}): void {\n this.#halt();\n this.#doc = doc;\n this.#excerpt = excerpt;\n this.#taal = undefined;\n this.#taalOverride = undefined;\n this.#bpmTweak = undefined; // per-song tweak does not carry across songs\n this.#resetPractice();\n this.#setState('ready');\n }\n\n /**\n * Taal mode: loop one avartan of a taal's theka (rhythm only, no melody) —\n * for a standalone theka player. `play()` loops indefinitely (tabla loop /\n * drum sequence) and fires `onBeat(beatInCycle)` once per matra on the draw\n * thread so the consumer can highlight the active bol / drum-staff note. The\n * taal's `id` should be a sampled taal (see `SAMPLED_TAALS`) for tabla audio;\n * `variation` picks a tabla loop variation. Stops any current playback.\n */\n loadTaal(taal: Taal): void {\n this.#halt();\n this.#taal = taal;\n this.#doc = undefined;\n this.#taalOverride = undefined;\n this.#bpmTweak = undefined;\n this.#resetPractice();\n this.#setState('ready');\n }\n\n /** Start (or resume) playback — from `from` (`part.row.note`, or `part.row`\n * for a line's start) when given, which also jumps there mid-play. Must be\n * triggered from a user gesture so the browser permits `AudioContext`\n * resume. */\n async play(from?: string): Promise<void> {\n if (this.#doc === undefined && this.#taal === undefined) return;\n if (from !== undefined) this.seek(from);\n // Still loading: the seek above has already moved where it will start.\n if (this.#state === 'playing' || this.#state === 'loading') return;\n const resume = this.#state === 'paused';\n // A fresh start claims 'loading' before its first await, so a second tap\n // while Tone downloads only moves the start instead of arranging twice.\n if (!resume) this.#setState('loading');\n let Tone: ToneModule;\n try {\n Tone = await this.#ensureTone();\n await Tone.start();\n } catch (err) {\n if (!resume) this.#setState('ready');\n throw err;\n }\n\n if (resume) {\n Tone.getTransport().start();\n this.#setState('playing');\n this.#armLimit();\n return;\n }\n\n // Fresh start — abort any in-flight stop fade and clear a left-running\n // transport before re-arranging. Only a running one: Tone's stop() on a\n // stopped clock cancels the earlier stop and re-stops now, which revives\n // the last run in between, and its stray ticks could swallow the first\n // note of this one.\n this.#cancelFade();\n const transport = Tone.getTransport();\n if (transport.state !== 'stopped') transport.stop();\n await this.#arrange(Tone);\n transport.start(undefined, this.#startSec() - this.#preroll());\n this.#startAt = null;\n this.#setState('playing');\n this.#armLimit();\n }\n\n /** Pause; `play()` resumes from the same position. */\n pause(): void {\n if (this.#tone === undefined || this.#state !== 'playing') return;\n this.#tone.getTransport().pause();\n this.#disarmLimit();\n this.#setState('paused');\n }\n\n /**\n * Move the playhead to `path` (`part.row.note`, or `part.row` for a line's\n * start). Playing, it jumps and keeps playing; paused or stopped, the next\n * `play()` starts there. A repeat follows the playhead: seeking outside the\n * repeated lines moves the repeat to the new line.\n */\n seek(path: string): void {\n const plan = this.#plan();\n if (plan !== undefined) this.#seekTo(plan, eventAt(plan.schedule.events, path, this.#at));\n }\n\n /** seek(), by event index — the pass, not just the line. */\n #seekTo(plan: { schedule: Schedule; lines: Line[] }, i: number): void {\n if (i < 0) return;\n const at = plan.schedule.events[i]!.path;\n this.#cursor = at;\n this.#at = i;\n this.#turn = false;\n const k = lineAt(plan.lines, i);\n const [a, b] = this.#loopSpan();\n if (this.#span !== null && (k < a || k > b)) this.#setSpan(plan.lines, k, k);\n this.#emitLoop();\n if (this.#timeline !== undefined && (this.#state === 'playing' || this.#state === 'paused')) {\n this.#applyLoop();\n this.#jump(this.#eventSec(i));\n if (this.#state === 'paused') this.#emitHighlight(at);\n } else {\n this.#startAt = i;\n this.#emitHighlight(at);\n }\n }\n\n /**\n * Repeat lines `from`..`to` (`part.row`, either order, inclusive; `to`\n * defaults to `from`). With no argument, the line under the playhead.\n * `null` stops repeating, and ends the sing-back with it. A playhead\n * outside the new repeat moves to its start; live while playing.\n */\n setLoop(from?: string | null, to?: string): void {\n this.#turn = false;\n if (from === null) {\n this.#span = this.#loop = null;\n this.#echo = false;\n this.#applyLoop();\n this.#emitLoop();\n return;\n }\n const plan = this.#plan();\n if (plan === undefined || plan.lines.length === 0) return;\n const { lines } = plan;\n const here = this.#at < 0 ? -1 : lineAt(lines, this.#at);\n const a = from === undefined ? Math.max(here, 0) : this.#lineOf(lines, from, here);\n this.#repeat(plan, a, to === undefined ? a : this.#lineOf(lines, to, a));\n }\n\n /** Repeat lines a..b (indices, either order); the playhead joins them. */\n #repeat(plan: { schedule: Schedule; lines: Line[] }, a: number, b: number): void {\n this.#setSpan(plan.lines, a, b);\n const [lo, hi] = this.#loopSpan();\n const here = this.#at < 0 ? -1 : lineAt(plan.lines, this.#at);\n if (here < lo || here > hi) return this.#seekTo(plan, plan.lines[lo]!.first);\n this.#applyLoop();\n this.#emitLoop();\n }\n\n /** The repeat's passes, and the rows they cover for the sheet's shading —\n * written order, since a span can cross a jump back to an earlier row. */\n #setSpan(lines: Line[], a: number, b: number): void {\n this.#span = [Math.min(a, b), Math.max(a, b)];\n const rows = lines.slice(this.#span[0], this.#span[1] + 1).map((line) => line.row).sort(byRow);\n this.#loop = { from: rows[0]!, to: rows.at(-1)! };\n }\n\n /** The line `path` names, at its pass nearest line `near`; the last line\n * when nothing sounds from there on. */\n #lineOf(lines: Line[], path: string, near: number): number {\n const k = lineFor(lines, path, near);\n return k < 0 ? lines.length - 1 : k;\n }\n\n /**\n * Follow every pass of the repeat with a silent one: the tabla and tanpura\n * keep time and the highlight keeps moving, but the melody rests so the\n * learner can sing the line back — the teacher sings, the student answers.\n * Turning it on with nothing repeating repeats the current line.\n */\n setEcho(on: boolean): void {\n this.#echo = on;\n this.#turn = false;\n if (on && this.#loop === null) this.setLoop();\n else this.#emitLoop();\n }\n\n /**\n * Move by whole lines. Like a player's previous-track button, a step back\n * from more than a matra into the line restarts that line first.\n * `±Infinity` goes to the first / last line.\n */\n stepLine(delta: number): void {\n const plan = this.#plan();\n if (plan === undefined || plan.lines.length === 0) return;\n const { lines, schedule } = plan;\n // No cursor yet: a step down lands on the first line.\n const k = this.#at < 0 ? -1 : lineAt(lines, this.#at);\n const into = k < 0 ? 0 : schedule.events[this.#at]!.beat - lines[k]!.beat;\n const step = delta < 0 && this.#state === 'playing' && into > 1 ? delta + 1 : delta;\n this.#seekTo(plan, lines[Math.min(Math.max(k + step, 0), lines.length - 1)]!.first);\n }\n\n /** Move by single notes (rests and holds included — each is a column). */\n stepNote(delta: number): void {\n const plan = this.#plan();\n const events = plan?.schedule.events ?? [];\n let i = this.#at;\n for (let left = Math.abs(delta); left > 0; left--) {\n do i += Math.sign(delta);\n while (events[i]?.glide === true);\n }\n if (plan !== undefined && events.length > 0) this.#seekTo(plan, Math.min(Math.max(i, 0), events.length - 1));\n }\n\n /**\n * Stop and rewind to the start. When sounding, the accompaniment (tabla /\n * metronome / tanpura, which otherwise loop) is gently faded out over\n * STOP_FADE_SEC before the transport is halted, so the rhythm doesn't keep\n * playing or cut abruptly; otherwise it halts immediately.\n */\n stop(): void {\n this.#disarmLimit();\n this.#listened = 0;\n this.#startAt = null;\n if (this.#turn) {\n this.#turn = false;\n this.#emitLoop();\n }\n if (this.#tone === undefined || this.#state === 'idle') {\n this.#halt();\n return;\n }\n if ((this.#state === 'playing' || this.#state === 'paused') && this.#master !== undefined) {\n const now = this.#tone.now();\n this.#master.gain.cancelScheduledValues(now);\n this.#master.gain.rampTo(0, STOP_FADE_SEC, now);\n this.#emitHighlight(null);\n this.#setState(this.#doc || this.#taal ? 'ready' : 'idle');\n this.#cancelFadeTimer();\n this.#fadeTimer = setTimeout(() => this.#halt(), STOP_FADE_SEC * 1000 + 60);\n return;\n }\n this.#halt();\n }\n\n /** Immediate, synchronous teardown: stop+rewind the transport, kill the\n * looping accompaniment, restore the master gain for the next play. */\n #halt(): void {\n this.#cancelFadeTimer();\n this.#disarmLimit();\n this.#timeline = undefined;\n this.#fence = 0;\n if (this.#tone !== undefined) {\n const transport = this.#tone.getTransport();\n transport.stop();\n transport.cancel(0);\n transport.position = 0;\n transport.loop = false;\n }\n // Dispose the looping tabla outright — a synced loop can outlive a bare\n // transport.stop(); #arrange recreates it on the next play.\n this.#disposeTabla();\n this.#restoreMasterGain();\n this.#scheduleIds = [];\n this.#emitHighlight(null);\n if (this.#state !== 'idle') this.#setState(this.#doc || this.#taal ? 'ready' : 'idle');\n }\n\n #cancelFadeTimer(): void {\n if (this.#fadeTimer !== undefined) {\n clearTimeout(this.#fadeTimer);\n this.#fadeTimer = undefined;\n }\n }\n\n /** Abort an in-flight stop-fade (timer + gain ramp) without touching the\n * transport — used when play() interrupts a fade. */\n #cancelFade(): void {\n this.#cancelFadeTimer();\n this.#restoreMasterGain();\n }\n\n #disposeTabla(): void {\n for (const { loop } of this.#tabla) loop.dispose();\n this.#tabla = [];\n }\n\n /** Snap each loop to a whole number of ITS OWN beats now the buffer length is\n * known, so a mistrimmed file phase-locks instead of drifting. */\n #quantizeTablaLoops(): void {\n for (const { loop, fileSpb } of this.#tabla) {\n if (loop.buffer?.loaded) loop.loopEnd = quantizeLoopEnd(loop.buffer.duration, fileSpb);\n }\n }\n\n /** Count down whatever listening time the preview cap has left. On the\n * audio clock, which keeps running while the page is hidden. */\n #armLimit(): void {\n const left = this.#opts.previewLimitSec - this.#listened;\n const context = this.#tone?.getContext();\n if (!Number.isFinite(left) || context === undefined) return;\n this.#listenedSince = context.now();\n this.#limitId = context.setTimeout(() => {\n this.#limitId = undefined;\n if (this.#state !== 'playing') return;\n this.stop();\n this.#opts.onLimit?.();\n }, Math.max(left, 0));\n }\n\n #disarmLimit(): void {\n const context = this.#tone?.getContext();\n if (this.#limitId === undefined || context === undefined) return;\n context.clearTimeout(this.#limitId);\n this.#limitId = undefined;\n this.#listened += context.now() - this.#listenedSince;\n }\n\n #restoreMasterGain(): void {\n if (this.#master !== undefined && this.#tone !== undefined) {\n this.#master.gain.cancelScheduledValues(this.#tone.now());\n this.#master.gain.value = 1;\n }\n }\n\n /* ----------------------------------------------------------------- */\n /* Settings (re-arrange from the top if mid-playback) */\n /* ----------------------------------------------------------------- */\n\n setTonic(tonic: string): void {\n this.#opts.tonic = tonic;\n this.#reapply();\n }\n setBpm(bpm: number): void {\n this.#bpmTweak = bpm;\n this.#reapply();\n }\n /** Update the preview cap (`Infinity` lifts it). Takes effect on next play. */\n setPreviewLimit(sec: number): void {\n this.#opts.previewLimitSec = sec;\n }\n setInstrument(instrument: InstrumentId): void {\n this.#opts.instrument = instrument;\n this.#reapply();\n }\n setRhythm(rhythm: RhythmMode): void {\n this.#opts.rhythm = rhythm;\n this.#reapply();\n }\n setTanpura(on: boolean): void {\n this.#opts.tanpura = on;\n this.#reapply();\n }\n /** Override the taal (null restores auto-detection from `meta.taal`). */\n setTaal(id: TaalId | null): void {\n this.#taalOverride = id ?? undefined;\n this.#taalAuto = id === null;\n this.#reapply();\n }\n\n /**\n * Wire highlight output to a `<swaralipi-sheet>` (or any highlight target).\n * Pass `{ autoScroll }` to keep the active note in view while playing.\n *\n * A sheet element also becomes the practice surface: a tap on a line plays\n * from the note under it (Shift stretches the repeat to that line), and\n * while it has focus — only then, so no key is taken from the page — Space\n * plays/pauses, ↑/↓ move by line, ←/→ by note, Home/End jump to the first /\n * last line, R repeats the line, T turns sing-back on/off, Esc stops the\n * repeat and Shift+↑/↓ stretch it. To gate a tap-to-play (a play quota, say),\n * `preventDefault()` its `swaralipi-seek` event in a capturing listener.\n */\n bindSheet(target: HighlightTarget, opts: BindSheetOptions = {}): void {\n // 'center' so the lyric directly below the note stays on screen too\n // ('nearest' can park the note at the bottom edge, hiding its lyric).\n const block: ScrollLogicalPosition | undefined =\n opts.autoScroll === true ? 'center' : opts.autoScroll || undefined;\n this.#paint = (path, yourTurn) => {\n target.clearHighlights();\n if (path === null) return;\n const el = target.highlight(path, yourTurn);\n if (block !== undefined && el !== null) {\n el.scrollIntoView({ block, inline: 'nearest', behavior: 'smooth' });\n }\n };\n this.#sheet = target;\n target.markLoop?.(this.#loop, this.#turn);\n this.#unbind?.abort();\n // The creator's canvas is a plain object: highlights only.\n if (!(target instanceof EventTarget)) return;\n const el = target as HighlightTarget & HTMLElement;\n const { signal } = (this.#unbind = new AbortController());\n el.setAttribute('seekable', '');\n signal.addEventListener('abort', () => el.removeAttribute('seekable'));\n el.addEventListener('swaralipi-seek', (e) => this.#onTap(e as SeekEvent), { signal });\n el.addEventListener('keydown', (e) => this.#onKey(e), { signal });\n }\n\n #onTap(e: SeekEvent): void {\n if (e.defaultPrevented) return;\n if (e.detail.extend) this.#extendLoop(e.detail.path);\n else void this.play(e.detail.path);\n }\n\n #onKey(e: KeyboardEvent): void {\n if (e.ctrlKey || e.metaKey || e.altKey) return;\n const shift = e.shiftKey;\n // Letters by physical key, so a Bengali or Hindi keyboard layout works too.\n const act: Record<string, (() => void) | undefined> = {\n Space: () => (this.#state === 'playing' ? this.pause() : void this.play()),\n ArrowUp: () => (shift ? this.#extendBy(-1) : this.stepLine(-1)),\n ArrowDown: () => (shift ? this.#extendBy(1) : this.stepLine(1)),\n ArrowLeft: () => this.stepNote(-1),\n ArrowRight: () => this.stepNote(1),\n Home: () => this.stepLine(-Infinity),\n End: () => this.stepLine(Infinity),\n KeyR: () => this.setLoop(this.#loop === null ? undefined : null),\n KeyT: () => this.setEcho(!this.#echo),\n Escape: this.#loop === null ? undefined : () => this.setLoop(null),\n };\n const run = act[e.code];\n if (run === undefined) return;\n e.preventDefault();\n run();\n }\n\n /** Grow the repeat (or start one from the current line) to take in `path`'s line. */\n #extendLoop(path: string): void {\n const plan = this.#plan();\n if (plan === undefined || plan.lines.length === 0) return;\n const here = this.#at < 0 ? -1 : lineAt(plan.lines, this.#at);\n const k = this.#lineOf(plan.lines, path, here);\n const [a, b] = this.#span ?? (here < 0 ? [k, k] : [here, here]);\n this.#repeat(plan, Math.min(a, k), Math.max(b, k));\n }\n\n /** Shift+↑/↓: one more line above / below the repeat. */\n #extendBy(delta: number): void {\n const plan = this.#plan();\n if (plan === undefined || plan.lines.length === 0) return;\n const here = this.#at < 0 ? 0 : lineAt(plan.lines, this.#at);\n const [a, b] = this.#span ?? [here, here];\n const k = Math.min(Math.max((delta < 0 ? a : b) + delta, 0), plan.lines.length - 1);\n this.#repeat(plan, Math.min(a, k), Math.max(b, k));\n }\n\n /**\n * Check whether an instrument's samples are reachable (its CDN is up / the\n * local files exist), via a one-byte ranged fetch of a representative sample.\n * A pass means Tone can actually load it. `false` for unknown ids, local\n * instruments with no `soundsBaseUrl`, or any network failure/timeout.\n */\n async checkInstrument(id: string, timeoutMs?: number): Promise<boolean> {\n const def = this.#resolveDef(id);\n if (def === undefined) return false;\n const url = instrumentSampleUrl(def, this.#opts.soundsBaseUrl);\n if (url === undefined) return false;\n return probeUrl(url, timeoutMs);\n }\n\n /**\n * Probe several instruments at once (default: the exposed `instruments`),\n * returning `{ id: available }`. Use it to disable picker options whose CDN\n * or files are down. Probes run concurrently; a check never throws.\n */\n async checkInstruments(\n ids: string[] = this.#opts.instruments,\n timeoutMs?: number,\n ): Promise<Record<string, boolean>> {\n const entries = await Promise.all(\n ids.map(async (id) => [id, await this.checkInstrument(id, timeoutMs)] as const),\n );\n return Object.fromEntries(entries);\n }\n\n /** Release all audio resources. The instance is unusable afterward. */\n dispose(): void {\n this.#halt();\n this.#unbind?.abort();\n this.#tone?.getTransport().off('loop', this.#onPass);\n for (const { sampler } of this.#samplers.values()) sampler.dispose();\n this.#samplers.clear();\n for (const { buffers } of this.#glide.values()) buffers.dispose();\n this.#glide.clear();\n this.#tanpura?.dispose();\n this.#metronome?.dispose();\n this.#disposeTabla();\n this.#drums?.dispose();\n this.#master?.dispose();\n this.#tanpura = this.#metronome = this.#drums = this.#master = undefined;\n }\n\n /* ----------------------------------------------------------------- */\n /* Internals */\n /* ----------------------------------------------------------------- */\n\n #taalOverride: TaalId | undefined;\n #taalAuto = true;\n\n #setState(state: PlayerState): void {\n this.#state = state;\n this.#opts.onState?.(state);\n }\n\n #emitHighlight(path: string | null, yourTurn = false): void {\n this.#paint?.(path, yourTurn);\n this.#opts.onHighlight?.(path, yourTurn);\n }\n\n #emitLoop(): void {\n this.#opts.onLoop?.({ loop: this.loop, echo: this.#echo, yourTurn: this.#turn });\n this.#sheet?.markLoop?.(this.#loop, this.#turn);\n }\n\n /** A new document starts with nothing repeated, from the top. */\n #resetPractice(): void {\n this.#cursor = this.#startAt = this.#loop = this.#span = null;\n this.#at = -1;\n this.#echo = this.#turn = false;\n this.#listened = 0;\n this.#emitLoop();\n }\n\n /** The timeline to navigate: the arranged one while playing, else built\n * fresh — it is pure and cheap, and a stopped player may have a new tonic\n * or tempo since. */\n #plan(): { schedule: Schedule; lines: Line[] } | undefined {\n if (this.#timeline !== undefined) return this.#timeline;\n if (this.#doc === undefined) return undefined;\n const schedule = buildSchedule(this.#doc, this.#scheduleOpts());\n return { schedule, lines: scheduleLines(schedule) };\n }\n\n /** The repeat as line indices (`[0, -1]`, i.e. empty, when off). */\n #loopSpan(): [number, number] {\n return this.#span ?? [0, -1];\n }\n\n /** The repeat's lines on the arranged timeline, cached for the per-note\n * checks (#hears), which run on every note. */\n #loopLines: [number, number] = [0, -1];\n\n /** Whether line `k` may sound: any line, unless a repeat holds others. */\n #hears(k: number): boolean {\n return this.#loop === null || (k >= this.#loopLines[0] && k <= this.#loopLines[1]);\n }\n\n /** Transport seconds of event `i`, pulled back by its কণ so the grace is\n * heard too. */\n #eventSec(i: number): number {\n const { schedule, spb, shift } = this.#timeline!;\n const ev = schedule.events[i]!;\n return Math.max((ev.beat - GRACE_STEP * ev.kan.length) * spb + shift, 0);\n }\n\n /** The repeat in transport seconds: from its first note's own start (its\n * কণ included) for exactly the lines' length, so every pass keeps the\n * tabla's phase. */\n #loopSec(): [number, number] {\n const { lines, spb } = this.#timeline!;\n const [a, b] = this.#loopLines;\n const start = this.#eventSec(lines[a]!.first);\n return [start, start + (lines[b]!.endBeat - lines[a]!.beat) * spb];\n }\n\n /** Put the repeat on the transport, or take it off. */\n #applyLoop(): void {\n const transport = this.#tone?.getTransport();\n if (transport === undefined || this.#timeline === undefined) return;\n this.#loopLines = this.#loopSpan();\n if (this.#span === null) {\n transport.loop = false;\n return;\n }\n transport.setLoopPoints(...this.#loopSec());\n transport.loop = true;\n }\n\n /** Where a fresh play() starts: a seek made while stopped, else the repeat,\n * else the top. */\n #startSec(): number {\n const events = this.#timeline?.schedule.events ?? [];\n if (this.#startAt !== null) return this.#eventSec(Math.min(this.#startAt, events.length - 1));\n return this.#span === null ? 0 : this.#loopSec()[0];\n }\n\n /** Move the transport; notes still ringing from the old place are let go. */\n #jump(sec: number): void {\n // Tone moves the position on its next tick, but the clock has not yet\n // walked the sliver of old timeline before it, so a note due there would\n // still sound ahead of the one just asked for. The fence drops those.\n const Tone = this.#tone!;\n const transport = Tone.getTransport();\n this.#fence = Tone.now();\n // A repeat wrapping in that same sliver would undo the jump outright: the\n // wrap resets Tone's tick offsets from its own moment on, the jump's\n // included. So no wrap until the jump has landed.\n if (transport.loop) {\n transport.loopEnd = this.#loopSec()[1] + 3600;\n Tone.getContext().setTimeout(() => this.#applyLoop(), 0.15);\n }\n transport.seconds = sec - this.#preroll();\n this.#voice?.releaseAll();\n }\n\n /** Audio time before which a note callback belongs to the timeline a seek\n * just left (see #jump). */\n #fence = 0;\n\n /** START_PREROLL_SEC in whole transport ticks: an offset between ticks\n * would shift every later repeat wrap by the remainder — measured, a\n * 0.8 ms splice in the tabla at each pass. */\n #preroll(): number {\n const transport = this.#tone!.getTransport();\n const perSec = (transport.bpm.value / 60) * transport.PPQ;\n return Math.ceil(START_PREROLL_SEC * perSec) / perSec;\n }\n\n /** The melody voice of the arrangement, for #jump. */\n #voice: MelodyVoice | undefined;\n\n /** The repeat wrapped. With sing-back on, the turn passes between the\n * player and the learner; the sheet is told at the wrap itself. */\n #onPass = (time: number): void => {\n if (this.#loop === null || !this.#echo) return;\n this.#turn = !this.#turn;\n this.#tone?.getDraw().schedule(() => this.#emitLoop(), time);\n };\n\n /** The taal one accompaniment segment plays: taal mode's, an explicit\n * setTaal override (pinned across the whole song, তালফেরতা included), else\n * the segment's own. `null` = a মুক্তছন্দ passage. */\n #segmentTaal(seg: TempoSegment): Taal | null | undefined {\n if (this.#taal !== undefined) return this.#taal;\n if (!this.#taalAuto && this.#taalOverride !== undefined) return TAALS[this.#taalOverride];\n return seg.taal;\n }\n\n /** The tabla variation to play: taal-mode taal's, the segment's own (auto\n * mode), else none — an explicit setTaal override plays the default variation. */\n #variation(taal: Taal | null | undefined): string | undefined {\n if (this.#taal !== undefined) return this.#taal.variation;\n return this.#taalAuto ? taal?.variation : undefined;\n }\n\n /** Resolve the active taal id: taal mode's taal, an explicit override, else\n * the doc's opening one (a তালফেরতা doc may carry it on its first row) — but\n * only when it names a sampled taal. */\n #taalId(): TaalId | undefined {\n const opening = this.#doc?.parts[0]?.rows[0]?.taal || this.#doc?.meta.taal;\n const id = this.#taal?.id ?? (!this.#taalAuto && this.#taalOverride !== undefined ? this.#taalOverride : opening?.id);\n return id !== undefined && id in TAALS ? (id as TaalId) : undefined;\n }\n\n /** Resolve an instrument id to its def (custom overrides built-ins; the\n * `pianoBaseUrl` shortcut self-hosts the built-in piano). */\n #resolveDef(id: string): InstrumentDef | undefined {\n const custom = this.#opts.customInstruments?.[id];\n if (custom) return custom;\n const def = INSTRUMENTS[id];\n if (def && id === 'piano' && this.#opts.pianoBaseUrl) {\n return { ...def, baseUrl: normalizeBase(this.#opts.pianoBaseUrl) };\n }\n return def;\n }\n\n /** A CDN-backed instrument that needs no `soundsBaseUrl` — used when the\n * chosen one is local-only and no samples host is set, or is unknown. */\n #fallbackInstrument(): string {\n const exposed = this.#opts.instruments.find((id) => {\n const d = this.#resolveDef(id);\n return d !== undefined && d.local !== true;\n });\n return exposed ?? 'harmonium';\n }\n\n /** The instrument actually used: the chosen one, unless it's local-only with\n * no `soundsBaseUrl` (or unknown), in which case a CDN fallback. */\n #effectiveInstrument(): string {\n const id = this.#opts.instrument;\n const def = this.#resolveDef(id);\n if (def === undefined) return this.#fallbackInstrument();\n if (def.local === true && !this.#opts.soundsBaseUrl) return this.#fallbackInstrument();\n return id;\n }\n\n #scheduleOpts() {\n return {\n tonic: this.#opts.tonic,\n baseOctave: this.#opts.baseOctave,\n laySpeeds: this.#opts.laySpeeds,\n repeats: this.#opts.repeats,\n excerpt: this.#excerpt,\n };\n }\n\n /** Effective tempo: snapped to the taal's available tabla tempos while a\n * tabla actually plays (so it never snaps to a bpm that taal lacks). */\n #effectiveBpm(): number {\n const id = this.#taalId();\n return this.usesTabla && id ? nearestTablaBpm(this.bpm, tablaBpms(id)) : this.bpm;\n }\n\n async #ensureTone(): Promise<ToneModule> {\n this.#tone ??= await import('tone');\n return this.#tone;\n }\n\n /** Hard stop → rebuild → restart, only while playing; otherwise just store.\n * Uses #halt (not the stop() fade) so a setting change restarts instantly,\n * from the note it was on — slowing down a repeated line keeps repeating it. */\n #reapply(): void {\n if (this.#state !== 'playing') return;\n const at = this.#at;\n this.#halt();\n this.#startAt = at < 0 ? null : at;\n void this.play();\n }\n\n /** The master bus everything routes through (created once, → destination). */\n #ensureMaster(Tone: ToneModule): Gain {\n this.#master ??= new Tone.Gain(1).toDestination();\n return this.#master;\n }\n\n /** Build the melody instrument(s)/rhythm/drone for the current settings and\n * wait for their buffers, then schedule everything on the Transport. */\n async #arrange(Tone: ToneModule): Promise<void> {\n if (this.#taal !== undefined) return this.#arrangeTaal(Tone);\n if (this.#doc === undefined) return;\n const base = this.#opts.soundsBaseUrl;\n const transport = Tone.getTransport();\n transport.cancel(0);\n transport.position = 0;\n transport.off('loop', this.#onPass).on('loop', this.#onPass);\n this.#scheduleIds = [];\n\n // Fresh master bus at unity gain (a prior stop-fade may have lowered it).\n this.#ensureMaster(Tone);\n this.#restoreMasterGain();\n\n const bpm = this.#effectiveBpm();\n transport.bpm.value = bpm;\n const spb = 60 / bpm;\n\n // Build the (pure) schedule first so the melody sampler loads only the\n // samples covering this song's pitch range — fewer files to fetch.\n const schedule: Schedule = buildSchedule(this.#doc, this.#scheduleOpts());\n const lines = scheduleLines(schedule);\n const range = midiRange(schedule);\n\n // --- melody instrument ---\n const id = this.#effectiveInstrument();\n const def = this.#resolveDef(id) ?? INSTRUMENTS.harmonium!;\n const melody = this.#buildMelody(Tone, id, base, range);\n this.#voice = melody;\n // মীড় voice: only built when the song actually glides somewhere. Must be\n // created here, with the other voices — anything built after the\n // `loadedOrWarn` below would still be downloading when the notes fire.\n const glide = schedule.events.some((ev) => ev.glide === true)\n ? this.#buildGlide(Tone, id, base, range)\n : undefined;\n\n // Pickup shift: push the melody so its sam locks to the looping accompaniment\n // (the rhythm keeps looping from 0, filling the count-in). Only when a rhythm\n // actually loops — with rhythm 'none' the shift would be pointless lead-in.\n const shift = this.#opts.rhythm !== 'none' ? schedule.pickupBeats * spb : 0;\n this.#timeline = { schedule, lines, spb, shift };\n\n // --- rhythm --- (one loop per লয় segment)\n this.#buildRhythm(Tone, transport, base, spb, schedule.tempo, shift);\n\n // --- tanpura drone ---\n this.#buildTanpura(Tone, transport, base, spb, schedule.tempo, shift);\n\n // wait for the (now-minimal) sample set to load before scheduling\n await loadedOrWarn(Tone);\n\n // Snap the tabla loop to a whole number of beats now its buffer length is\n // known, so a mistrimmed loop phase-locks instead of drifting (no-op for a\n // correctly trimmed file).\n this.#quantizeTablaLoops();\n\n // --- notes + highlights ---\n const draw = Tone.getDraw();\n const mediaLead = Math.min(MEDIA_LEAD_SEC, spb); // never more than a matra ahead\n\n // Every note is a persistent transport event (`schedule`, not\n // `scheduleOnce`), so a seek back or a repeat's next pass hears it again.\n // Each asks, as it comes due, whether its line is inside the repeat and\n // whether this pass is the learner's to sing.\n let line = 0;\n schedule.events.forEach((ev, i) => {\n while (lines[line + 1] !== undefined && lines[line + 1]!.first <= i) line++;\n const k = line;\n const heard = (time: number) => time >= this.#fence && this.#hears(k);\n const sounds = (time: number) => heard(time) && !this.#turn;\n const at = ev.beat * spb + shift;\n // A glide target is sounded by the attack it slides from, not on its own.\n if (ev.glide !== true) {\n for (const g of graceTouches(ev)) {\n const graceName = midiToSampleName(g.midi);\n transport.schedule((time) => {\n if (sounds(time)) melody.triggerAttackRelease(graceName, spb * 0.4, time);\n }, Math.max(g.beat * spb + shift, 0));\n }\n }\n if (ev.midi !== null && ev.glide !== true) {\n const name = midiToSampleName(ev.midi);\n const dur = Math.max(ev.durationBeats * spb, 0.05);\n const targets = glide !== undefined ? glideTargets(schedule.events, i) : [];\n if (targets.length > 0 && glide !== undefined) {\n // Legs are offsets from the attack; the transport hands us the audio\n // time of that attack, which is what the automation must be anchored to.\n const last = targets[targets.length - 1]!;\n const legs = [\n { midi: ev.midi, at: 0 },\n ...targets.map((t) => ({ midi: t.midi!, at: (t.beat - ev.beat) * spb })),\n ];\n const end = (last.beat + last.durationBeats - ev.beat) * spb;\n transport.schedule((time) => {\n if (!sounds(time)) return;\n triggerGlide(\n Tone,\n glide.buffers,\n glide.urls,\n this.#ensureMaster(Tone),\n legs.map((l) => ({ midi: l.midi, at: time + l.at })),\n time + end,\n def.release ?? 1,\n );\n }, at);\n } else {\n transport.schedule((time) => {\n if (sounds(time)) melody.triggerAttackRelease(name, dur, time);\n }, at);\n }\n }\n // Two clocks, deliberately: the audio one (survives a hidden page) carries\n // the line to whatever is not drawing, a beat-fraction early so a lock\n // screen has time to repaint; the draw thread keeps the on-screen\n // highlight exactly on the note.\n if (this.#opts.onEvent !== undefined) {\n transport.schedule((time) => {\n if (heard(time)) this.#opts.onEvent?.(ev.path);\n }, Math.max(at - mediaLead, 0));\n }\n // The learner's pass still moves the highlight: it shows where to sing.\n transport.schedule((time) => {\n if (!heard(time)) return;\n const turn = this.#turn;\n this.#cursor = ev.path;\n this.#at = i;\n draw.schedule(() => this.#emitHighlight(ev.path, turn), time);\n }, at);\n });\n this.#applyLoop();\n\n // clear highlight + auto-stop at the end\n const endAt = playDurationSec(schedule, spb, this.#opts.rhythm);\n transport.scheduleOnce((time) => {\n this.#opts.onEvent?.(null);\n draw.schedule(() => this.#emitHighlight(null), time);\n }, schedule.totalBeats * spb + shift);\n transport.scheduleOnce(() => this.stop(), endAt);\n }\n\n /** Taal mode: loop one avartan forever (tabla loop / drum sequence via\n * #buildRhythm), firing onBeat + a `String(beatInCycle)` highlight each matra\n * on the draw thread. No melody, no tanpura, no auto-stop — it plays until\n * stop(). */\n async #arrangeTaal(Tone: ToneModule): Promise<void> {\n if (this.#taal === undefined) return;\n const base = this.#opts.soundsBaseUrl;\n const transport = Tone.getTransport();\n transport.cancel(0);\n transport.position = 0;\n this.#scheduleIds = [];\n\n this.#ensureMaster(Tone);\n this.#restoreMasterGain();\n\n const bpm = this.#effectiveBpm();\n transport.bpm.value = bpm;\n const spb = 60 / bpm;\n\n this.#buildRhythm(Tone, transport, base, spb, TAAL_MODE_TEMPO, 0);\n await loadedOrWarn(Tone);\n this.#quantizeTablaLoops();\n\n const draw = Tone.getDraw();\n const n = Math.max(1, this.#taal.numBeats);\n let beat = 0;\n const id = transport.scheduleRepeat((time) => {\n const b = beat % n;\n draw.schedule(() => {\n this.#emitHighlight(String(b));\n this.#opts.onBeat?.(b);\n }, time);\n beat += 1;\n }, spb, 0);\n this.#scheduleIds.push(id);\n }\n\n /** Build (or reuse) the melody sampler for `id`, loading only the samples\n * covering `range`. A cached sampler is reused while it still covers the\n * range; otherwise it's rebuilt (so changing songs/tonic widens it lazily). */\n #buildMelody(\n Tone: ToneModule,\n id: string,\n base: string | undefined,\n range: { lo: number; hi: number } | undefined,\n ): MelodyVoice {\n const def = this.#resolveDef(id) ?? INSTRUMENTS.harmonium!;\n const master = this.#ensureMaster(Tone);\n const cached = this.#samplers.get(id);\n if (cached && (range === undefined || (cached.lo <= range.lo && cached.hi >= range.hi))) {\n return cached.sampler;\n }\n cached?.sampler.dispose();\n const sampler = createSampler(Tone, def, base, range).connect(master);\n this.#samplers.set(id, { sampler, lo: range?.lo ?? -Infinity, hi: range?.hi ?? Infinity });\n return sampler;\n }\n\n /** Build (or reuse) the মীড় glide buffers for `id` — the same samples the\n * Sampler uses, kept as raw buffers so a note can be started once and its\n * playbackRate automated. Cached and range-widened exactly like #buildMelody. */\n #buildGlide(\n Tone: ToneModule,\n id: string,\n base: string | undefined,\n range: { lo: number; hi: number } | undefined,\n ) {\n const cached = this.#glide.get(id);\n if (cached && (range === undefined || (cached.lo <= range.lo && cached.hi >= range.hi))) return cached;\n cached?.buffers.dispose();\n const def = this.#resolveDef(id) ?? INSTRUMENTS.harmonium!;\n const built = createBuffers(Tone, def, base, range);\n const entry = { ...built, lo: range?.lo ?? -Infinity, hi: range?.hi ?? Infinity };\n this.#glide.set(id, entry);\n return entry;\n }\n\n /**\n * Accompaniment, one লয় / তাল segment at a time. A tempo change under the\n * melody is a real tempo change under the drum: the tabla loop is rebuilt at\n * the segment's own bpm — its own recorded file when the set has one at that\n * tempo, else the nearest file time-stretched by `GrainPlayer` (which\n * stretches *without* transposing, unlike a plain playbackRate) — and the\n * click / drum / drone patterns re-space their interval. A তালফেরতা swaps the\n * theka the same way: each segment loops its own taal's file (or pattern, or\n * click cycle), and a মুক্তছন্দ segment rests. A document with neither mark\n * has exactly one segment, so this is the old single-loop path.\n */\n #buildRhythm(\n Tone: ToneModule,\n transport: ReturnType<ToneModule['getTransport']>,\n base: string | undefined,\n spb: number,\n segments: readonly TempoSegment[],\n shift: number,\n ): void {\n // dispose stale loops so they don't double up after a re-arrange\n this.#disposeTabla();\n\n const master = this.#ensureMaster(Tone);\n const rhythm = this.#opts.rhythm;\n if (rhythm === 'none' || (base === undefined && rhythm !== 'drums')) return;\n\n segments.forEach((seg, i) => {\n const own = this.#segmentTaal(seg);\n // An explicit মুক্তছন্দ passage has no theka to keep: the rhythm rests.\n if (own === null) return;\n const taalId = own !== undefined && own.id in TAALS ? (own.id as TaalId) : undefined;\n // Segment 0 starts at 0 so the accompaniment fills the pickup count-in;\n // the last one is left open-ended so it rings under the final note's tail.\n const from = i === 0 ? 0 : seg.beat * spb + shift;\n const to = i === segments.length - 1 ? Infinity : seg.endBeat * spb + shift;\n const beatSec = spb / seg.scale; // seconds per matra inside this segment\n const span = to === Infinity ? undefined : to - from;\n // Which matra of the segment a click lands on, read off the transport\n // rather than counted, so it is still right after a seek or a repeat.\n const beatAt = (time: number) => Math.round((transport.getSecondsAtTime(time) - from) / beatSec);\n\n if (rhythm === 'tabla' && taalId !== undefined && SAMPLED_TAALS.has(taalId) && base !== undefined) {\n const bpm = 60 / beatSec;\n const fileBpm = nearestTablaBpm(bpm, tablaBpms(taalId));\n const rate = bpm / fileBpm;\n // Retune the recorded loop to the song's Sa; an unshifted tonic at a\n // recorded tempo stays on the plain Player (no granulation at all).\n const semis = tablaShiftSemitones(this.#tonicSemitone());\n const url = tablaUrl(base, taalId, fileBpm, this.#variation(own));\n this.#grain ??= seekableGrain(Tone);\n const loop = (rate === 1 && semis === 0\n ? new Tone.Player({ url, loop: true })\n : new this.#grain({\n url,\n loop: true,\n playbackRate: rate,\n detune: semis * 100,\n grainSize: TABLA_GRAIN_SEC,\n overlap: TABLA_GRAIN_OVERLAP_SEC,\n })\n ).connect(master);\n loop.sync().start(from);\n if (span !== undefined) {\n // The next loop starts clean on the boundary (a সম); this one just\n // decays under it instead of being cut mid-skin. Volume automation is\n // audio-clock, so it has to be armed from inside a transport callback\n // — a persistent one that restores the level once the loop has\n // stopped, since a repeat wrapping back brings this segment round again.\n this.#scheduleIds.push(\n transport.schedule((t) => {\n loop.volume.setValueAtTime(0, t);\n loop.volume.linearRampToValueAtTime(-40, t + LAY_TAIL_SEC);\n loop.volume.setValueAtTime(0, t + LAY_TAIL_SEC + 0.05);\n }, to),\n );\n loop.stop(to + LAY_TAIL_SEC);\n }\n this.#tabla.push({ loop, fileSpb: 60 / fileBpm });\n return;\n }\n\n if (rhythm === 'drums') {\n this.#drums ??= createDrumKit(Tone).connect(master);\n const drums = this.#drums;\n // Prefer the canonical TAALS def (has khaali), else the segment's own taal.\n const pattern = drumPattern(this.#taal ?? (taalId !== undefined ? TAALS[taalId] : own) ?? { numBeats: 4, sam: 0 });\n this.#scheduleIds.push(\n transport.scheduleRepeat(\n (time) => {\n const voice = pattern[beatAt(time) % pattern.length]!;\n if (drums.has(voice)) drums.player(voice).start(time);\n },\n beatSec,\n from,\n span,\n ),\n );\n return;\n }\n\n // metronome fallback: a click each beat, louder on sam (cycle start).\n // The segment's own numBeats even when its taal isn't sampled (so a pickup\n // song's sam accent lands right, matching the shift).\n this.#metronome ??= createMetronome(Tone, base!).connect(master);\n const metro = this.#metronome;\n const cycle = (this.#taal ?? seg.taal)?.numBeats ?? 4;\n this.#scheduleIds.push(\n transport.scheduleRepeat(\n (time) => {\n metro.volume.setValueAtTime(beatAt(time) % cycle === 0 ? 0 : -8, time);\n metro.start(time);\n },\n beatSec,\n from,\n span,\n ),\n );\n });\n }\n\n #buildTanpura(\n Tone: ToneModule,\n transport: ReturnType<ToneModule['getTransport']>,\n base: string | undefined,\n spb: number,\n segments: readonly TempoSegment[],\n shift: number,\n ): void {\n if (!this.#opts.tanpura || base === undefined) return;\n\n // Pa–Sa–Sa–Sa drone, one pluck every two beats, cycling.\n const tonicPc = ((this.#tonicSemitone() % 12) + 12) % 12;\n const sa = TANPURA_PCS[tonicPc]!;\n const pa = TANPURA_PCS[(tonicPc + 7) % 12]!;\n\n // Load only the two pitch classes the drone uses (not all 12); rebuild if\n // the tonic changed.\n const key = `${sa},${pa}`;\n if (this.#tanpura === undefined || this.#tanpuraKey !== key) {\n this.#tanpura?.dispose();\n this.#tanpura = createTanpura(Tone, base, [sa, pa]).connect(this.#ensureMaster(Tone));\n this.#tanpuraKey = key;\n }\n const players = this.#tanpura;\n players.volume.value = -14;\n\n const pattern = [pa, sa, sa, sa];\n // The drone keeps the লয়'s pulse too — one pluck every two matra.\n segments.forEach((seg, k) => {\n const from = k === 0 ? 0 : seg.beat * spb + shift;\n const to = k === segments.length - 1 ? Infinity : seg.endBeat * spb + shift;\n const every = (spb * 2) / seg.scale;\n this.#scheduleIds.push(\n transport.scheduleRepeat(\n (time) => {\n const stem = pattern[Math.round((transport.getSecondsAtTime(time) - from) / every) % pattern.length]!;\n if (players.has(stem)) players.player(stem).start(time);\n },\n every,\n from,\n to === Infinity ? undefined : to - from,\n ),\n );\n });\n }\n\n #tonicSemitone(): number {\n return parseTonic(this.#opts.tonic ?? this.#doc?.meta.tonic);\n }\n}\n","/**\n * Offline audio export — render a swaralipi doc to a downloadable WAV or MP3\n * **entirely in the browser** (no server): `Tone.Offline` renders the same\n * melody / tabla / tanpura arrangement the live player builds into an\n * OfflineAudioContext (faster than real time), then a pure encoder writes the\n * PCM out.\n *\n * Like the player, Tone is **dynamically imported** (so importing this module\n * in Node/SSR never touches `AudioContext`) and the MP3 path dynamically\n * imports lamejs (an *optional* peer dep — WAV needs no dependency at all).\n * The actual render needs a browser (Node has no OfflineAudioContext); the two\n * encoders below are pure and unit-testable on their own.\n *\n * ponytail: the melody/rhythm/tanpura scheduling mirrors player.ts `#arrange`\n * (minus highlights / caching / fades) — keep the two in sync.\n */\nimport type { GrainPlayer, Player } from 'tone';\nimport type { Swaralipi, Taal } from '../spec/index.js';\nimport { TAALS, type TaalId } from '../spec/taals.js';\nimport type { LaySpeeds } from '../spec/lay.js';\nimport { midiToSampleName, parseTonic } from './pitch.js';\nimport { buildSchedule, glideTargets, graceTouches, type Schedule, type TempoSegment } from './schedule.js';\nimport { alignLyrics, lyricCues, type Excerpt } from './lyrics.js';\nimport type { RhythmMode } from './player.js';\nimport {\n DEFAULT_SOUNDS_BASE,\n INSTRUMENTS,\n SAMPLED_TAALS,\n TABLA_GRAIN_OVERLAP_SEC,\n TABLA_GRAIN_SEC,\n TANPURA_PCS,\n createBuffers,\n createDrumKit,\n createMetronome,\n createSampler,\n createTanpura,\n drumPattern,\n nearestTablaBpm,\n normalizeBase,\n quantizeLoopEnd,\n tablaBpms,\n triggerGlide,\n tablaShiftSemitones,\n tablaUrl,\n type InstrumentDef,\n type InstrumentId,\n type ToneModule,\n} from './instruments.js';\n\nexport type AudioFormat = 'wav' | 'mp3';\n\n/** Seconds the outgoing tabla loop decays under the incoming one at a লয়\n * change (mirrors the player's LAY_TAIL_SEC). */\nconst LAY_TAIL_SEC = 0.12;\n\nexport interface AudioExportOptions {\n /** Play only the notes singing these stretches of the text (see alignLyrics). */\n excerpt?: Excerpt;\n /** The song's words: when given, the result carries their `cues` (an LRC's timing). */\n lyrics?: string;\n /** Samples host (santoor/tabla/tanpura/metronome). Default the project CDN. */\n soundsBaseUrl?: string;\n /** Self-host the grand piano (see the player's `pianoBaseUrl`). */\n pianoBaseUrl?: string;\n /** Extra melody instruments, keyed by id (see the player's option). */\n customInstruments?: Record<string, InstrumentDef>;\n /** Tonic (Sa). Accepts `C`, `C#`, `cs`… Default: doc tonic, else `C`. */\n tonic?: string;\n /** Tempo in matra/min — the **দ্রুত** (fast) tempo; লয় marks scale down from\n * it. Default: `meta.bpm`, else 90. Snapped to the tabla grid when a sampled\n * tabla actually plays. */\n bpm?: number;\n /** Override the লয় tempo factors (see LAY_SPEEDS / meta.laySpeeds). */\n laySpeeds?: LaySpeeds;\n /** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */\n baseOctave?: number;\n /** Melody instrument id. Default `piano`. */\n instrument?: InstrumentId;\n /** Include the notation (melody) voice. Default true. */\n melody?: boolean;\n /** Rhythm accompaniment: `tabla` (→ metronome for unsampled taals), `drums`\n * (Western drumset following sam/tali/khaali), `metronome`, or `none`.\n * Default `none` — the base export is notation only. */\n rhythm?: RhythmMode;\n /** Taal for the rhythm: an explicit id, or `auto` (from `meta.taal`). Default\n * `auto`. Only used when `rhythm` isn't `none`. */\n taal?: TaalId | 'auto';\n /** Include the tanpura drone. Default false. */\n tanpura?: boolean;\n /** Sing the song's form (repeats, returns to the asthayi), as the player\n * does. Default true; false keeps the written order. */\n repeats?: boolean;\n /** Output format. Default `wav` (lossless, zero-dependency). `mp3` needs the\n * optional peer dep `@breezystack/lamejs`. */\n format?: AudioFormat;\n /** MP3 bitrate in kbps. Default 192. */\n mp3Kbps?: number;\n /** Output channels. Default 1 (the content is monophonic and centred, so mono\n * halves the file with no audible loss); set 2 for stereo. */\n channels?: 1 | 2;\n /** Sample rate. Default 44100. */\n sampleRate?: number;\n /** Fade the last N seconds so a looped tabla/tanpura doesn't hard-cut at the\n * render boundary. Default 0.4. */\n fadeOutSec?: number;\n}\n\nexport interface AudioExportResult {\n /** The encoded audio, ready to download or upload. */\n blob: Blob;\n /** Suggested `<title>.<ext>` download filename. */\n filename: string;\n mimeType: string;\n /** Rendered length in seconds. */\n durationSec: number;\n /** Each sung line and its words, in seconds on this file's timeline (given `lyrics`). */\n cues?: LyricCue[];\n}\n\nexport interface LyricCue {\n sec: number;\n words: { sec: number; text: string }[];\n}\n\n/** MIDI span (incl. কণ/রেশ graces) of a schedule, for sample subsetting. */\nfunction midiRange(schedule: Schedule): { lo: number; hi: number } | undefined {\n let lo = Infinity;\n let hi = -Infinity;\n for (const ev of schedule.events) {\n for (const m of [ev.midi, ...ev.kan, ...ev.resh]) {\n if (m !== null) {\n if (m < lo) lo = m;\n if (m > hi) hi = m;\n }\n }\n }\n return lo <= hi ? { lo, hi } : undefined;\n}\n\n/** Seconds of the song turned into nodes ahead of the renderer (see renderOffline). */\nconst AHEAD_SEC = 2;\n\n/**\n * Tone.Offline, made quick. Tone runs its clock over the whole song before the first sample, so\n * every note already exists as a pending node — and Chrome and WebKit process every pending node\n * for every 128-frame block: 240 s of 3000 notes took 152 s (Chrome) and 89 s (WebKit), against\n * 1.6 s and 1.2 s with each note made just ahead of the renderer. So the clock runs a chunk at a\n * time from the render's own suspend points. Firefox has no OfflineAudioContext.suspend() (157),\n * but renders the whole graph at once ~12x faster, so it gets the whole clock up front. Neither\n * path yields with setTimeout, which a background tab throttles to once a second.\n */\nasync function renderOffline(\n Tone: ToneModule,\n build: (context: InstanceType<ToneModule['OfflineContext']>) => Promise<void>,\n durationSec: number,\n channels: number,\n sampleRate: number,\n): Promise<AudioBuffer> {\n // Chunked needs a native context — Tone's wrapper (standardized-audio-context) has no\n // suspend() — and Tone needs the listener's AudioParams, which Firefox lacks.\n const chunked = 'suspend' in OfflineAudioContext.prototype && 'positionX' in AudioListener.prototype;\n const context = chunked\n ? new Tone.OfflineContext(new OfflineAudioContext(channels, Math.ceil(durationSec * sampleRate), sampleRate))\n : new Tone.OfflineContext(channels, durationSec, sampleRate);\n const raw = context.rawContext as unknown as OfflineAudioContext;\n const original = Tone.getContext();\n Tone.setContext(context);\n try {\n await build(context);\n } finally {\n Tone.setContext(original);\n }\n // Tone's own clock loop (OfflineContext#_renderClock), run only as far as `until`.\n const clock = context as unknown as { _currentTime: number; emit(event: 'tick'): void };\n const run = (until: number) => {\n while (clock._currentTime <= Math.min(until, durationSec)) {\n clock.emit('tick');\n clock._currentTime += 128 / sampleRate;\n }\n };\n if (chunked) {\n run(2 * AHEAD_SEC);\n for (let t = AHEAD_SEC; t < durationSec; t += AHEAD_SEC) {\n void raw.suspend(t).then(() => {\n run(t + 2 * AHEAD_SEC);\n void raw.resume();\n });\n }\n } else {\n run(Infinity);\n }\n return raw.startRendering();\n}\n\n/** Resolve the melody instrument def (mirrors the player's #resolveDef): a\n * custom override, the piano self-host shortcut, a CDN fallback for a local\n * instrument with no host, else the requested built-in. */\nfunction pickDef(id: string, o: AudioExportOptions): InstrumentDef {\n const def = o.customInstruments?.[id] ?? INSTRUMENTS[id];\n if (def === undefined) return INSTRUMENTS.harmonium!; // unknown id → CDN fallback\n if (id === 'piano' && o.pianoBaseUrl) return { ...def, baseUrl: normalizeBase(o.pianoBaseUrl) };\n if (def.local === true && !o.soundsBaseUrl) return INSTRUMENTS.harmonium!; // local needs a host\n return def;\n}\n\n/** The active taal id (explicit override, else the doc's opening one — a\n * তালফেরতা doc may carry it on its first row), or undefined for an\n * unknown/absent taal (→ metronome falls back to a 4-beat cycle). */\nfunction resolveTaal(doc: Swaralipi, taal: AudioExportOptions['taal']): TaalId | undefined {\n const id = taal !== undefined && taal !== 'auto' ? taal : (doc.parts[0]?.rows[0]?.taal || doc.meta.taal)?.id;\n return id !== undefined && id in TAALS ? (id as TaalId) : undefined;\n}\n\n/** Strip filesystem-hostile characters (keeps Bengali/Unicode letters). */\nfunction safeName(title: string | undefined): string {\n return (title ?? '').replace(/[\\\\/:*?\"<>|]+/g, '').trim() || 'swaralipi';\n}\n\n/**\n * Render a swaralipi doc to an audio Blob in the browser. Runs in an\n * OfflineAudioContext — no user gesture and no server needed. Throws in an\n * environment without Web Audio (Node/SSR) or, for `format: 'mp3'`, when the\n * optional `@breezystack/lamejs` peer dependency is not installed.\n */\nexport async function exportAudio(\n doc: Swaralipi,\n options: AudioExportOptions = {},\n): Promise<AudioExportResult> {\n const Tone: ToneModule = await import('tone');\n\n const base = options.soundsBaseUrl ?? DEFAULT_SOUNDS_BASE;\n const format = options.format ?? 'wav';\n const channels = options.channels ?? 1;\n const sampleRate = options.sampleRate ?? 44100;\n const fadeOutSec = options.fadeOutSec ?? 0.4;\n const rhythm: RhythmMode = options.rhythm ?? 'none';\n const withMelody = options.melody ?? true;\n const withTanpura = options.tanpura ?? false;\n\n const schedule = buildSchedule(doc, {\n tonic: options.tonic,\n baseOctave: options.baseOctave,\n laySpeeds: options.laySpeeds,\n repeats: options.repeats ?? true,\n excerpt: options.excerpt,\n });\n const range = midiRange(schedule);\n\n const taalId = resolveTaal(doc, options.taal);\n // An explicit taal is pinned across the whole song; 'auto' follows each\n // segment's own (তালফেরতা).\n const pinned: Taal | undefined =\n options.taal !== undefined && options.taal !== 'auto' && taalId !== undefined ? TAALS[taalId] : undefined;\n const usesTabla = rhythm === 'tabla' && taalId !== undefined && SAMPLED_TAALS.has(taalId) && !!base;\n\n const reqBpm = options.bpm ?? doc.meta.bpm ?? 90;\n const bpm = usesTabla && taalId ? nearestTablaBpm(reqBpm, tablaBpms(taalId)) : reqBpm;\n const spb = 60 / bpm;\n\n const id = options.instrument ?? 'piano';\n const def = pickDef(id, options);\n // Pickup shift: push the melody so its sam locks to the looping accompaniment\n // (mirrors the player; only when a rhythm loops). Lengthens the render tail.\n const shift = rhythm !== 'none' ? schedule.pickupBeats * spb : 0;\n const durationSec = Math.max(schedule.totalBeats * spb + shift + (def.release ?? 1) + fadeOutSec + 0.5, 0.5);\n\n const rendered = await renderOffline(\n Tone,\n async ({ transport }) => {\n transport.bpm.value = bpm;\n const master = new Tone.Gain(1).toDestination();\n\n // --- melody (the notation, sounded) ---\n if (withMelody) {\n const sampler = createSampler(Tone, def, base, range).connect(master);\n // মীড় glide voice — same samples, started once and pitch-automated\n // (mirrors the player; only built when the song actually glides).\n const glide = schedule.events.some((ev) => ev.glide === true)\n ? createBuffers(Tone, def, base, range)\n : undefined;\n schedule.events.forEach((ev, i) => {\n if (ev.glide === true) return;\n for (const g of graceTouches(ev)) {\n const name = midiToSampleName(g.midi);\n transport.scheduleOnce((t) => sampler.triggerAttackRelease(name, spb * 0.4, t), Math.max(g.beat * spb + shift, 0));\n }\n if (ev.midi === null) return;\n const at = ev.beat * spb + shift;\n const dur = Math.max(ev.durationBeats * spb, 0.05);\n const targets = glide !== undefined ? glideTargets(schedule.events, i) : [];\n if (targets.length > 0 && glide !== undefined) {\n const last = targets[targets.length - 1]!;\n const legs = [\n { midi: ev.midi, at: 0 },\n ...targets.map((t) => ({ midi: t.midi!, at: (t.beat - ev.beat) * spb })),\n ];\n const end = (last.beat + last.durationBeats - ev.beat) * spb;\n transport.scheduleOnce((t) => {\n triggerGlide(\n Tone,\n glide.buffers,\n glide.urls,\n master,\n legs.map((l) => ({ midi: l.midi, at: t + l.at })),\n t + end,\n def.release ?? 1,\n );\n }, at);\n } else {\n const name = midiToSampleName(ev.midi);\n transport.scheduleOnce((t) => sampler.triggerAttackRelease(name, dur, t), at);\n }\n });\n }\n\n // --- rhythm (looped tabla, drumset, or a metronome click) ---\n // One pass per লয় / তাল segment, exactly like the player's #buildRhythm:\n // the tabla is rebuilt at each segment's own tempo and taal (its own\n // recorded file when one exists, else the nearest time-stretched by\n // GrainPlayer), and a মুক্তছন্দ segment rests.\n const tablas: { loop: Player | GrainPlayer; fileSpb: number }[] = [];\n if (rhythm !== 'none' && base) {\n const drums = rhythm === 'drums' ? createDrumKit(Tone).connect(master) : undefined;\n let metro: Player | undefined;\n const semis = tablaShiftSemitones(parseTonic(options.tonic ?? doc.meta.tonic));\n\n schedule.tempo.forEach((seg: TempoSegment, i) => {\n const own = pinned ?? seg.taal;\n if (own === null) return;\n const segId = own !== undefined && own.id in TAALS ? (own.id as TaalId) : undefined;\n const from = i === 0 ? 0 : seg.beat * spb + shift;\n const to = i === schedule.tempo.length - 1 ? Infinity : seg.endBeat * spb + shift;\n const beatSec = spb / seg.scale;\n const span = to === Infinity ? undefined : to - from;\n\n if (rhythm === 'tabla' && segId !== undefined && SAMPLED_TAALS.has(segId)) {\n const segBpm = 60 / beatSec;\n const fileBpm = nearestTablaBpm(segBpm, tablaBpms(segId));\n const rate = segBpm / fileBpm;\n const url = tablaUrl(base, segId, fileBpm, pinned === undefined ? own?.variation : undefined);\n const loop = (rate === 1 && semis === 0\n ? new Tone.Player({ url, loop: true })\n : new Tone.GrainPlayer({\n url,\n loop: true,\n playbackRate: rate,\n detune: semis * 100,\n grainSize: TABLA_GRAIN_SEC,\n overlap: TABLA_GRAIN_OVERLAP_SEC,\n })\n ).connect(master);\n loop.sync().start(from);\n if (span !== undefined) {\n transport.scheduleOnce((t) => {\n loop.volume.setValueAtTime(0, t);\n loop.volume.linearRampToValueAtTime(-40, t + LAY_TAIL_SEC);\n }, to);\n loop.stop(to + LAY_TAIL_SEC);\n }\n tablas.push({ loop, fileSpb: 60 / fileBpm });\n } else if (drums !== undefined) {\n const pattern = drumPattern(segId !== undefined ? TAALS[segId] : (own ?? { numBeats: 4, sam: 0 }));\n let beat = 0;\n transport.scheduleRepeat(\n (time) => {\n const voice = pattern[beat % pattern.length]!;\n if (drums.has(voice)) drums.player(voice).start(time);\n beat += 1;\n },\n beatSec,\n from,\n span,\n );\n } else {\n const click = (metro ??= createMetronome(Tone, base).connect(master));\n const cycle = own?.numBeats ?? 4;\n let beat = 0;\n transport.scheduleRepeat(\n (time) => {\n click.volume.setValueAtTime(beat % cycle === 0 ? 0 : -8, time);\n click.start(time);\n beat += 1;\n },\n beatSec,\n from,\n span,\n );\n }\n });\n }\n\n // --- tanpura drone (Pa–Sa–Sa–Sa, one pluck every two beats) ---\n if (withTanpura && base) {\n const tonicPc = ((parseTonic(options.tonic ?? doc.meta.tonic) % 12) + 12) % 12;\n const sa = TANPURA_PCS[tonicPc]!;\n const pa = TANPURA_PCS[(tonicPc + 7) % 12]!;\n const players = createTanpura(Tone, base, [sa, pa]).connect(master);\n players.volume.value = -14;\n const pattern = [pa, sa, sa, sa];\n schedule.tempo.forEach((seg: TempoSegment, k) => {\n const from = k === 0 ? 0 : seg.beat * spb + shift;\n const to = k === schedule.tempo.length - 1 ? Infinity : seg.endBeat * spb + shift;\n let i = 0;\n transport.scheduleRepeat(\n (time) => {\n const stem = pattern[i % pattern.length]!;\n if (players.has(stem)) players.player(stem).start(time);\n i += 1;\n },\n (spb * 2) / seg.scale,\n from,\n to === Infinity ? undefined : to - from,\n );\n });\n }\n\n // Buffers must be loaded before the (one-shot) render, or they arrive too\n // late to be heard — the async callback is awaited, so this is the fix.\n await Tone.loaded();\n // Snap a mistrimmed tabla loop to whole beats of ITS OWN recorded tempo\n // now its length is known (loop points are buffer time, not song time).\n for (const { loop, fileSpb } of tablas) {\n if (loop.buffer?.loaded) loop.loopEnd = quantizeLoopEnd(loop.buffer.duration, fileSpb);\n }\n\n // Soften the tail so looped accompaniment doesn't click off at the edge.\n if (fadeOutSec > 0) {\n master.gain.setValueAtTime(1, Math.max(durationSec - fadeOutSec, 0));\n master.gain.linearRampToValueAtTime(0, durationSec);\n }\n transport.start(0);\n },\n durationSec,\n channels,\n sampleRate,\n );\n\n const chans: Float32Array[] = [];\n for (let c = 0; c < rendered.numberOfChannels; c++) chans.push(rendered.getChannelData(c));\n\n const bytes =\n format === 'mp3'\n ? await encodeMp3(chans, rendered.sampleRate, options.mp3Kbps)\n : encodeWav(chans, rendered.sampleRate);\n const mimeType = format === 'mp3' ? 'audio/mpeg' : 'audio/wav';\n const cues = options.lyrics === undefined\n ? undefined\n : lyricCues(schedule.events, alignLyrics(doc, options.lyrics), options.lyrics).map((cue) => ({\n sec: cue.beat * spb + shift,\n words: cue.words.map((word) => ({ sec: word.beat * spb + shift, text: word.text })),\n }));\n return {\n blob: new Blob([bytes as BlobPart], { type: mimeType }),\n filename: `${safeName(doc.meta.title)}.${format}`,\n mimeType,\n durationSec: rendered.duration,\n ...(cues === undefined ? {} : { cues }),\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Pure encoders (browser-free, unit-testable) */\n/* ------------------------------------------------------------------ */\n\n/** Clamp a float sample to a 16-bit signed integer. */\nfunction toInt16(f: number): number {\n const s = f < -1 ? -1 : f > 1 ? 1 : f;\n return s < 0 ? s * 0x8000 : s * 0x7fff;\n}\n\n/**\n * Encode planar float channels to a 16-bit PCM WAV (RIFF). Pure — no Web Audio\n * — so it runs (and tests) in Node. 16-bit PCM is lossless CD quality and plays\n * everywhere; float/24-bit skipped (add if mastering-grade output is needed).\n */\nexport function encodeWav(channels: Float32Array[], sampleRate: number): Uint8Array {\n const numCh = channels.length;\n const frames = channels[0]?.length ?? 0;\n const bytesPerSample = 2;\n const blockAlign = numCh * bytesPerSample;\n const dataSize = frames * blockAlign;\n const buf = new ArrayBuffer(44 + dataSize);\n const view = new DataView(buf);\n const str = (off: number, s: string) => {\n for (let i = 0; i < s.length; i++) view.setUint8(off + i, s.charCodeAt(i));\n };\n\n str(0, 'RIFF');\n view.setUint32(4, 36 + dataSize, true);\n str(8, 'WAVE');\n str(12, 'fmt ');\n view.setUint32(16, 16, true); // PCM fmt chunk size\n view.setUint16(20, 1, true); // format = PCM\n view.setUint16(22, numCh, true);\n view.setUint32(24, sampleRate, true);\n view.setUint32(28, sampleRate * blockAlign, true); // byte rate\n view.setUint16(32, blockAlign, true);\n view.setUint16(34, bytesPerSample * 8, true); // bits per sample\n str(36, 'data');\n view.setUint32(40, dataSize, true);\n\n let off = 44;\n for (let f = 0; f < frames; f++) {\n for (let c = 0; c < numCh; c++) {\n view.setInt16(off, toInt16(channels[c]![f]!), true);\n off += 2;\n }\n }\n return new Uint8Array(buf);\n}\n\n/** Convert a float channel to the Int16 samples lamejs expects. */\nfunction floatToInt16(f: Float32Array): Int16Array {\n const out = new Int16Array(f.length);\n for (let i = 0; i < f.length; i++) out[i] = toInt16(f[i]!);\n return out;\n}\n\nfunction concatBytes(chunks: Uint8Array[]): Uint8Array {\n const total = chunks.reduce((n, c) => n + c.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const c of chunks) {\n out.set(c, off);\n off += c.length;\n }\n return out;\n}\n\n/** Load the optional lamejs encoder, tolerating named/default export shapes. */\nasync function loadLame(): Promise<{ new (channels: number, sampleRate: number, kbps: number): Mp3EncoderLike }> {\n try {\n const mod = (await import('@breezystack/lamejs')) as unknown as {\n Mp3Encoder?: new (c: number, s: number, k: number) => Mp3EncoderLike;\n default?: { Mp3Encoder: new (c: number, s: number, k: number) => Mp3EncoderLike };\n };\n const Mp3Encoder = mod.Mp3Encoder ?? mod.default?.Mp3Encoder;\n if (!Mp3Encoder) throw new Error('no Mp3Encoder export');\n return Mp3Encoder;\n } catch {\n throw new Error(\n 'MP3 export needs the optional peer dependency \"@breezystack/lamejs\" — ' +\n 'install it, or export as WAV (format: \"wav\").',\n );\n }\n}\n\ninterface Mp3EncoderLike {\n encodeBuffer(left: Int16Array, right?: Int16Array): Int8Array;\n flush(): Int8Array;\n}\n\n/**\n * A streaming MP3 encoder: feed 16-bit PCM in any number of pieces, get one MP3 — one encoder\n * delay, so a track joined from several renders keeps its timing. lamejs is **dynamically\n * imported** and an *optional* peer dependency (LGPL-3.0). Samples go in 1152-frame blocks (a\n * multiple of 576, lamejs' preferred size).\n */\nexport async function mp3Stream(\n sampleRate = 44100,\n kbps = 192,\n channels: 1 | 2 = 1,\n): Promise<{ push(left: Int16Array, right?: Int16Array): void; end(): Uint8Array[] }> {\n const Mp3Encoder = await loadLame();\n const enc = new Mp3Encoder(channels, sampleRate, kbps);\n const out: Uint8Array[] = [];\n const keep = (chunk: Int8Array) => {\n if (chunk.length > 0) out.push(new Uint8Array(chunk));\n };\n const block = 1152;\n return {\n push(left, right) {\n for (let i = 0; i < left.length; i += block) {\n const l = left.subarray(i, i + block);\n keep(right ? enc.encodeBuffer(l, right.subarray(i, i + block)) : enc.encodeBuffer(l));\n }\n },\n end() {\n keep(enc.flush());\n return out;\n },\n };\n}\n\n/** Encode planar float channels to MP3 via lamejs (see mp3Stream). WAV needs no dependency, so\n * only reach for this when a compressed file is wanted. */\nexport async function encodeMp3(\n channels: Float32Array[],\n sampleRate: number,\n kbps = 192,\n): Promise<Uint8Array> {\n const numCh = Math.min(channels.length, 2) as 1 | 2; // lamejs is mono or stereo\n const mp3 = await mp3Stream(sampleRate, kbps, numCh);\n mp3.push(floatToInt16(channels[0] ?? new Float32Array()), numCh > 1 ? floatToInt16(channels[1]!) : undefined);\n return concatBytes(mp3.end());\n}\n","/**\n * MIDI export — write a swaralipi doc to a downloadable Standard MIDI File.\n *\n * Unlike the audio export this needs **no Tone and no AudioContext**: MIDI is\n * just note events, and `buildSchedule` already gives us (midi, beat,\n * durationBeats) per note. So the whole thing is pure bytes — it runs (and\n * tests) in plain Node, and carries no dependency (the SMF format is trivial),\n * which keeps it clear of any redistribution/license question.\n *\n * Scope = the **melody voice**, plus — when `drums` is on — the Western-drumset\n * translation of the taal (the same `drumPattern` the player sequences) written\n * as a **separate GM channel-10 track**. Tabla is prerecorded audio loops with\n * no per-stroke note data, so there's nothing to turn into MIDI notes; tanpura\n * is a fixed background drone. A `.mid` here is the notation line (+ optional\n * drums) — the user opens it in any DAW and assigns instruments.\n */\nimport type { Swaralipi } from '../spec/index.js';\nimport { TAALS } from '../spec/taals.js';\nimport type { LaySpeeds } from '../spec/lay.js';\nimport type { Excerpt } from './lyrics.js';\nimport { GRACE_STEP, buildSchedule, glideTargets, graceTouches, type Schedule, type TempoSegment } from './schedule.js';\nimport { MEEND_HOLD, drumPattern, type DrumVoice } from './instruments.js';\nimport { sCurve } from './pitch.js';\n\n/** Pulses per quarter note. One matra (beat) == one quarter note. */\nconst PPQ = 480;\n\nexport interface MidiExportOptions {\n /** Play only the notes singing these stretches of the text (see alignLyrics). */\n excerpt?: Excerpt;\n /** Tonic (Sa). Accepts `C`, `C#`, `cs`… Default: doc tonic, else `C`. */\n tonic?: string;\n /** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */\n baseOctave?: number;\n /** Tempo in matra/min written as the file's tempo — the **দ্রুত** tempo;\n * লয় marks come out as longer note values against it, not as tempo changes.\n * Default `meta.bpm`, else 90. */\n bpm?: number;\n /** Override the লয় tempo factors (see LAY_SPEEDS / meta.laySpeeds). */\n laySpeeds?: LaySpeeds;\n /** Track name meta-event. Default the song title. */\n name?: string;\n /** Also export the taal's drumset pattern as a separate GM channel-10 track. */\n drums?: boolean;\n /** Sing the song's form (repeats, returns to the asthayi), as the player\n * does. Default true; false keeps the written order. */\n repeats?: boolean;\n}\n\nexport interface MidiExportResult {\n blob: Blob;\n /** Suggested `<title>.mid` filename. */\n filename: string;\n mimeType: string;\n}\n\n/** Variable-length quantity (7 bits/byte, high bit = continue). */\nfunction vlq(n: number): number[] {\n const out = [n & 0x7f];\n n >>>= 7;\n while (n > 0) {\n out.unshift((n & 0x7f) | 0x80);\n n >>>= 7;\n }\n return out;\n}\n\n/** UTF-8 bytes of a string (Bengali titles survive; most DAWs read UTF-8). */\nfunction utf8(s: string): number[] {\n return [...new TextEncoder().encode(s)];\n}\n\nfunction u32be(n: number): number[] {\n return [(n >>> 24) & 0xff, (n >>> 16) & 0xff, (n >>> 8) & 0xff, n & 0xff];\n}\n\ninterface RawEvent {\n tick: number;\n on: boolean;\n note: number;\n vel: number;\n ch: number;\n /** Status byte override; `note`/`vel` then carry the two data bytes. Used\n * for the pitch-bend and RPN messages a মীড় needs. */\n status?: number;\n meta?: number[];\n}\n\n/**\n * Pitch-bend range, in semitones, declared once via RPN 0. The GM default is\n * only ±2, but corpus মীড়s reach 7 semitones and a basic meend \"can range from\n * a simple span of 2 notes to a whole octave\" (ITC SRA), so the file asks for\n * ±12. A DAW that ignores the RPN will play the glides too wide.\n */\nconst BEND_RANGE = 12;\n\n/** Bend steps written per মীড় leg — the S-curve sampled fine enough to read\n * as a continuous slide in any sequencer. */\nconst BEND_STEPS = 16;\n\n/** 14-bit pitch-bend message for a signed semitone offset (0 = centre). */\nfunction bendEvent(tick: number, semitones: number): RawEvent {\n const raw = Math.round(8192 + (semitones / BEND_RANGE) * 8192);\n const value = Math.min(Math.max(raw, 0), 16383);\n return { tick, on: false, status: 0xe0, note: value & 0x7f, vel: (value >> 7) & 0x7f, ch: 0 };\n}\n\n/** RPN 0 = pitch-bend sensitivity, so the ±12 semitone glides land right. */\nfunction bendRangeSetup(): RawEvent[] {\n const cc = (num: number, val: number): RawEvent => ({ tick: 0, on: false, status: 0xb0, note: num, vel: val, ch: 0 });\n return [cc(101, 0), cc(100, 0), cc(6, BEND_RANGE), cc(38, 0), cc(101, 127), cc(100, 127)];\n}\n\n/** General MIDI channel-10 (index 9) percussion note per drumset voice. */\nconst DRUM_NOTE: Record<DrumVoice, number> = {\n kick: 36,\n snare: 38,\n hihat: 42, // closed hi-hat\n tom1: 48,\n tom2: 45,\n tom3: 41,\n};\n\n/** Serialise sorted raw events into an MTrk chunk (bytes, incl. header). */\nfunction trackChunk(raw: RawEvent[], head: number[]): number[] {\n // Time order; at equal ticks: release, then any bend/CC, then attack — so a\n // repeated pitch never hangs and a bend reset can't touch the next note.\n const rank = (e: RawEvent) => (e.status !== undefined ? 1 : e.on ? 2 : 0);\n raw.sort((a, b) => a.tick - b.tick || rank(a) - rank(b));\n const track = [...head];\n let last = 0;\n for (const e of raw) {\n if (e.meta) {\n track.push(...vlq(e.tick - last), ...e.meta);\n last = e.tick;\n continue;\n }\n const status = e.status !== undefined ? e.status | (e.ch & 0x0f) : (e.on ? 0x90 : 0x80) | (e.ch & 0x0f);\n track.push(...vlq(e.tick - last), status, e.note & 0x7f, e.vel & 0x7f);\n last = e.tick;\n }\n track.push(...vlq(0), 0xff, 0x2f, 0x00); // end of track\n return [0x4d, 0x54, 0x72, 0x6b, ...u32be(track.length), ...track];\n}\n\n/**\n * Encode a schedule to a Standard MIDI File. Melody rides channel 0; when\n * `drums` is given, its per-matra voices ride a second GM channel-10 track\n * (the file becomes format 1). `drums` is one pattern for the whole song, or a\n * function picking each লয় / তাল segment's own (তালফেরতা; `undefined` = rest).\n * Pure — no Tone, no browser — directly testable.\n */\nfunction melodyEvents(schedule: Schedule, offset = 0): RawEvent[] {\n const melody: RawEvent[] = [];\n const hasGlide = schedule.events.some((ev) => ev.glide === true);\n if (hasGlide) melody.push(...bendRangeSetup());\n schedule.events.forEach((ev, i) => {\n // A মীড় target is not struck: it is bent into from the note before it.\n if (ev.glide === true) return;\n // Each grace lasts one step, so it never overlaps the next grace or a কণ's attack.\n for (const g of graceTouches(ev)) {\n const on = Math.max(Math.round(g.beat * PPQ) + offset, 0);\n melody.push({ tick: on, on: true, note: g.midi, vel: 70, ch: 0 });\n melody.push({ tick: Math.max(on + 1, Math.round((g.beat + GRACE_STEP) * PPQ) + offset), on: false, note: g.midi, vel: 0, ch: 0 });\n }\n if (ev.midi === null) return;\n const start = Math.round(ev.beat * PPQ) + offset;\n const targets = glideTargets(schedule.events, i);\n const last = targets[targets.length - 1] ?? ev;\n const end = Math.max(Math.round((last.beat + last.durationBeats) * PPQ) + offset, start + 1);\n melody.push({ tick: start, on: true, note: ev.midi, vel: 100, ch: 0 });\n melody.push({ tick: end, on: false, note: ev.midi, vel: 0, ch: 0 });\n\n // One held note + a bent S-curve per leg: hold the source svara for\n // MEEND_HOLD of the gap, then roll into the target, arriving on its matra.\n let from = ev;\n for (const to of targets) {\n const glideStart = from.beat + (to.beat - from.beat) * MEEND_HOLD;\n for (let n = 0; n <= BEND_STEPS; n++) {\n const u = n / BEND_STEPS;\n const beat = glideStart + (to.beat - glideStart) * u;\n const semis = from.midi! - ev.midi + (to.midi! - from.midi!) * sCurve(u);\n melody.push(bendEvent(Math.round(beat * PPQ) + offset, semis));\n }\n from = to;\n }\n if (targets.length > 0) melody.push(bendEvent(end, 0)); // centre before the next note\n });\n return melody;\n}\n\nfunction drumEvents(schedule: Schedule, drums: DrumVoice[] | ((seg: TempoSegment) => DrumVoice[] | undefined), offset = 0): RawEvent[] {\n const drum: RawEvent[] = [];\n for (const seg of schedule.tempo) {\n const pattern = typeof drums === 'function' ? drums(seg) : drums;\n if (!pattern?.length) continue;\n // One stroke per written matra, spaced by the segment's লয়; each segment\n // restarts its pattern on the সম it begins with.\n const end = seg === schedule.tempo[schedule.tempo.length - 1] ? Math.ceil(schedule.totalBeats) : seg.endBeat;\n for (let k = 0; seg.beat + k / seg.scale < end - 1e-6; k++) {\n const note = DRUM_NOTE[pattern[k % pattern.length]!];\n const t = Math.round((seg.beat + k / seg.scale) * PPQ) + offset;\n drum.push({ tick: t, on: true, note, vel: 100, ch: 9 });\n drum.push({ tick: t + Math.round(PPQ / 4), on: false, note, vel: 0, ch: 9 }); // one-shot: short gate\n }\n }\n return drum;\n}\n\nfunction midiFile(chunks: number[][]): Uint8Array {\n const format = chunks.length > 1 ? 1 : 0;\n const header = [0x4d, 0x54, 0x68, 0x64, ...u32be(6), 0x00, format, (chunks.length >> 8) & 0xff, chunks.length & 0xff, (PPQ >> 8) & 0xff, PPQ & 0xff];\n return new Uint8Array([...header, ...chunks.flat()]);\n}\n\nfunction meta(type: number, data: number[]): number[] {\n return [0xff, type, ...vlq(data.length), ...data];\n}\n\nexport function encodeMidi(\n schedule: Schedule,\n opts: { bpm: number; name?: string; drums?: DrumVoice[] | ((seg: TempoSegment) => DrumVoice[] | undefined) },\n): Uint8Array {\n // Tempo lives on the first track alongside the name.\n const usPerBeat = Math.round(60_000_000 / opts.bpm);\n const head: number[] = [];\n if (opts.name) head.push(...vlq(0), 0xff, 0x03, ...vlq(utf8(opts.name).length), ...utf8(opts.name));\n head.push(...vlq(0), 0xff, 0x51, 0x03, (usPerBeat >> 16) & 0xff, (usPerBeat >> 8) & 0xff, usPerBeat & 0xff);\n\n const chunks = [trackChunk(melodyEvents(schedule), head)];\n\n if (typeof opts.drums === 'function' || (opts.drums && opts.drums.length > 0)) {\n const drum = drumEvents(schedule, opts.drums);\n chunks.push(trackChunk(drum, [...vlq(0), 0xff, 0x03, ...vlq(5), 0x44, 0x72, 0x75, 0x6d, 0x73])); // \"Drums\"\n }\n\n return midiFile(chunks);\n}\n\n/** The song as exported: its form sung (repeats), its লয় baked into the durations. */\nfunction exportSchedule(doc: Swaralipi, o: MidiExportOptions): Schedule {\n return buildSchedule(doc, { tonic: o.tonic, baseOctave: o.baseOctave, laySpeeds: o.laySpeeds, repeats: o.repeats ?? true, excerpt: o.excerpt });\n}\n\n/** Each segment drums its own taal (তালফেরতা); a মুক্তছন্দ segment rests. */\nfunction taalDrums(seg: TempoSegment): DrumVoice[] | undefined {\n if (seg.taal === null) return undefined;\n const id = seg.taal?.id;\n return drumPattern(id !== undefined && id in TAALS ? TAALS[id as keyof typeof TAALS] : { numBeats: 4, sam: 0 });\n}\n\n/** Strip filesystem-hostile characters (keeps Bengali/Unicode letters). */\nfunction safeName(title: string | undefined): string {\n return (title ?? '').replace(/[\\\\/:*?\"<>|]+/g, '').trim() || 'swaralipi';\n}\n\n/**\n * Export a swaralipi doc to a `.mid` Blob (melody voice only). No browser APIs\n * beyond `Blob` (present in Node 20+ too), so it works client-side or server-side.\n */\nexport function exportMidi(doc: Swaralipi, options: MidiExportOptions = {}): MidiExportResult {\n // লয় is baked into the durations: at one MIDI tempo, a বিলম্বিত passage is\n // the same notes written twice as long — which is what a DAW should show.\n const schedule = exportSchedule(doc, options);\n const bpm = options.bpm ?? doc.meta.bpm ?? 90;\n const bytes = encodeMidi(schedule, { bpm, name: options.name ?? doc.meta.title, drums: options.drums ? taalDrums : undefined });\n return {\n blob: new Blob([bytes as BlobPart], { type: 'audio/midi' }),\n filename: `${safeName(doc.meta.title)}.mid`,\n mimeType: 'audio/midi',\n };\n}\n\n/** Several songs on one timeline (a whole dance-drama), back to back with two beats' rest:\n * each song opens with its own tempo and a marker naming it; drums share one channel-10 track. */\nexport function exportMidiSet(items: { doc: Swaralipi; options?: MidiExportOptions }[], name: string): MidiExportResult {\n const melody: RawEvent[] = [];\n const drum: RawEvent[] = [];\n let beat = 0;\n for (const { doc, options = {} } of items) {\n const schedule = exportSchedule(doc, options);\n const tick = beat * PPQ;\n const usPerBeat = Math.round(60_000_000 / (options.bpm ?? doc.meta.bpm ?? 90));\n const at = (bytes: number[]): RawEvent => ({ tick, on: false, note: 0, vel: 0, ch: 0, meta: bytes });\n melody.push(at(meta(0x51, [(usPerBeat >> 16) & 0xff, (usPerBeat >> 8) & 0xff, usPerBeat & 0xff])));\n melody.push(at(meta(0x06, utf8(options.name ?? doc.meta.title ?? ''))), ...melodyEvents(schedule, tick));\n if (options.drums) drum.push(...drumEvents(schedule, taalDrums, tick));\n beat += Math.ceil(schedule.totalBeats) + 2;\n }\n const chunks = [trackChunk(melody, [...vlq(0), ...meta(0x03, utf8(name))])];\n if (drum.length > 0) chunks.push(trackChunk(drum, [...vlq(0), ...meta(0x03, utf8('Drums'))]));\n const bytes = midiFile(chunks);\n return { blob: new Blob([bytes as BlobPart], { type: 'audio/midi' }), filename: `${safeName(name)}.mid`, mimeType: 'audio/midi' };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/spec/taals.ts","../../src/spec/grace.ts","../../src/spec/svara.ts","../../src/player/pitch.ts","../../src/spec/lay.ts","../../src/player/lyrics.ts","../../src/convert/codec.ts","../../src/player/repeats.ts","../../src/player/schedule.ts","../../src/player/instruments.ts","../../src/player/player.ts","../../src/player/export.ts","../../src/player/midi.ts"],"names":["j","EPS","last","matra","el","sounds","LAY_TAIL_SEC","midiRange","off","mod","leadIn","safeName","bytes"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Taal } from './schema.js';\n\n/**\n * Reference definitions for the taals the player will sample:\n * adachautaal, dadra, ektaal, jhaptaal, kehrwa, rupak, shashthi, teentaal,\n * jhampak, dhamaar, rupakra, khemta.\n *\n * `numBeats` and the `bhaags` given below are standard Hindustani taal theory.\n * `bhaags` is omitted where a single canonical division isn't well-agreed\n * (adachautaal) — we assert only what's uncontested. `sam` is beat 0 for all.\n *\n * Tabla loops live under `tabla/<id>/` by default; per-taal variation and\n * skip-bpm overrides (e.g. shashthi → `tabla/shashthi-pro/`) are in\n * instruments.ts's `TABLA_VARIATIONS`.\n */\nexport const TAALS = {\n dadra: { id: 'dadra', numBeats: 6, bhaags: [3, 3], sam: 0, khaali: [3] },\n kehrwa: { id: 'kehrwa', numBeats: 8, bhaags: [4, 4], sam: 0, khaali: [4] },\n rupak: { id: 'rupak', numBeats: 7, bhaags: [3, 2, 2], sam: 0, khaali: [0] },\n jhaptaal: { id: 'jhaptaal', numBeats: 10, bhaags: [2, 3, 2, 3], sam: 0, khaali: [5] },\n ektaal: { id: 'ektaal', numBeats: 12, bhaags: [2, 2, 2, 2, 2, 2], sam: 0, khaali: [2, 6] },\n adachautaal: { id: 'adachautaal', numBeats: 14, sam: 0 },\n choutaal: { id: 'choutaal', numBeats: 12, bhaags: [2, 2, 2, 2, 2, 2], sam: 0, khaali: [2, 6] }, // চৌতাল\n shashthi: { id: 'shashthi', numBeats: 6, bhaags: [2, 4], sam: 0 }, // ষষ্ঠী\n teora: { id: 'teora', numBeats: 7, bhaags: [3, 2, 2], sam: 0 }, // তেওরা\n teentaal: { id: 'teentaal', numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] },\n aratheka: { id: 'aratheka', numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] }, // আড়াঠেকা\n jhampak: { id: 'jhampak', numBeats: 5, bhaags: [3, 2], sam: 0 }, // ঝম্পক\n dhamaar: { id: 'dhamaar', numBeats: 14, bhaags: [5, 2, 3, 4], sam: 0, khaali: [7] }, // ধামার\n rupakra: { id: 'rupakra', numBeats: 8, bhaags: [3, 2, 3], sam: 0 }, // রূপকড়া\n khemta: { id: 'khemta', numBeats: 12, bhaags: [3, 3, 3, 3], sam: 0, khaali: [6] }, // খেমটা\n} as const satisfies Record<string, Taal>;\n\nexport type TaalId = keyof typeof TAALS;\n\n/**\n * The name a তালফেরতা song's header prints instead of one taal (Swarabitan /\n * Gitabitan's own word; gitabitan.io's taxonomy spells it তাল-ফেরতা). The\n * taals themselves live on the rows (`row.taal`).\n */\nexport const TAAL_FERTA = 'তালফেরতা';\n\n/** Whether a printed taal name is the তালফেরতা heading (either spelling). */\nexport function isTaalFerta(name: string | undefined): boolean {\n return name !== undefined && name.normalize('NFC').replace(/[\\s-]/g, '') === TAAL_FERTA;\n}\n\n/**\n * Whether two taal marks name the same accompaniment — the তালফেরতা test.\n * `null` (মুক্তছন্দ) and `undefined` (no taal) are only equal to themselves.\n * Compared by value: a row restating the taal in force is not a change.\n */\nexport function sameTaal(a: Taal | null | undefined, b: Taal | null | undefined): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n return a.id === b.id && a.numBeats === b.numBeats && a.variation === b.variation && String(a.bhaags) === String(b.bhaags);\n}\n","/**\n * কণ / রেশ readers. Zod-free on purpose: the viewer and the player import\n * this directly (the `spec/index.js` barrel would drag zod into their\n * browser bundles — see `taals.ts` for the same rule).\n */\nimport type { Grace, Note, Svara } from './schema.js';\n\n/** Normalise a grace payload to its note list; the legacy tuple is one note. */\nexport function graceNotes(grace: Grace | undefined): Note[] {\n if (grace === undefined) return [];\n return typeof grace[0] === 'string' ? [{ svara: grace as Svara }] : (grace as Note[]);\n}\n","/**\n * Which svaras admit which alteration — স and প are অচল (immovable), ম has\n * only its তীব্র (কড়ি) form, and র গ ধ ন only their কোমল form. The notation\n * fonts encode exactly this (no glyph exists for a কোমল প), so a flag the\n * sheet cannot draw must not move the pitch either.\n *\n * Zod-free on purpose: the viewer and the player import this directly (the\n * `spec/index.js` barrel would drag zod into their browser bundles — see\n * `taals.ts` and `grace.ts` for the same rule).\n */\nimport type { SvaraLetter } from './schema.js';\n\nexport function hasKomal(letter: SvaraLetter): boolean {\n return letter === 'r' || letter === 'g' || letter === 'd' || letter === 'n';\n}\n\nexport function hasTivra(letter: SvaraLetter): boolean {\n return letter === 'm';\n}\n","/**\n * Pure svara → pitch math for the player. No Tone, no audio — unit-testable\n * in plain Node and shared by the scheduler.\n *\n * The model: a tonic (Sa) pitch-class + a per-note scale degree + octave\n * register + komal/tivra/microtone accidentals → an absolute MIDI number,\n * which the Tone.Sampler pitch-shifts from the nearest santoor sample.\n */\nimport { graceNotes } from '../spec/grace.js';\nimport { hasKomal, hasTivra } from '../spec/svara.js';\nimport type { Note, Octave, SvaraLetter } from '../spec/index.js';\n\n/** Octave register offset in octaves, relative to madhyam (middle). */\nexport const OCTAVE_OFFSET: Record<Octave, number> = {\n 'ati-mandra': -2,\n mandra: -1,\n madhyam: 0,\n taar: 1,\n 'ati-taar': 2,\n};\n\n/**\n * Shuddha (natural) scale degrees in semitones above Sa — the Bilawal/major\n * thaat that Rabindrasangeet swaralipi notates against. `d` = dha, `n` = ni\n * (standard sargam letter convention).\n */\nexport const SHUDDHA: Record<SvaraLetter, number> = {\n s: 0,\n r: 2,\n g: 4,\n m: 5,\n p: 7,\n d: 9,\n n: 11,\n};\n\n/** Sharp-spelled pitch-class names, index = semitone 0–11. */\nconst SHARP_NAMES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] as const;\n\n/** Pitch-class lookup. Accepts sharps (`C#`, `Cs`, `cs`) and flats (`Db`). */\nconst PITCH_CLASS: Record<string, number> = {\n c: 0,\n 'c#': 1,\n db: 1,\n d: 2,\n 'd#': 3,\n eb: 3,\n e: 4,\n 'e#': 5,\n fb: 4,\n f: 5,\n 'f#': 6,\n gb: 6,\n g: 7,\n 'g#': 8,\n ab: 8,\n a: 9,\n 'a#': 10,\n bb: 10,\n b: 11,\n 'b#': 0,\n cb: 11,\n};\n\n/**\n * Parse a tonic string to a pitch-class 0–11. Accepts `C`, `C#`, `Db`, and\n * the player/sample lowercase-`s` sharp form (`cs`, `Cs`); case-insensitive.\n * Unknown input falls back to 0 (C).\n */\nexport function parseTonic(tonic: string | undefined): number {\n if (!tonic) return 0;\n const key = tonic.trim().toLowerCase().replace(/s/g, '#');\n return PITCH_CLASS[key] ?? 0;\n}\n\n/**\n * Semitone of a note relative to Sa (degree + accidentals), ignoring octave.\n * Returns null when the note carries no pitch (rest/sustain-hold/bar).\n *\n * Microtones (অল্পকোমল/অতিকোমল) are approximated to the komal pitch — a\n * documented v1 limitation (the sampler can't bend a sub-komal microtone\n * cleanly per note); matches the viewer's placeholder treatment.\n */\nexport function svaraSemitone(note: Note): number | null {\n if (note.svara === undefined) return null;\n const [, letter] = note.svara;\n let semi = SHUDDHA[letter];\n // Only alter what the notation can actually draw: স/প are অচল and ম has no\n // কোমল form, so a stray flag on one of those must sound as written (the\n // viewer falls back to the shuddha glyph — see glyphs.ts).\n if ((note.komal === true || note.microtone !== undefined) && hasKomal(letter)) semi -= 1;\n if (note.tivra === true && hasTivra(letter)) semi += 1;\n return semi;\n}\n\n/**\n * Absolute MIDI for a note, or null when it has no pitch. madhyam Sa lands on\n * the tonic in octave `baseOctave` (C4 = MIDI 60). Out-of-sample registers\n * are produced by the Sampler pitch-shifting from the nearest recorded note.\n */\nexport function svaraToMidi(note: Note, tonicPc: number, baseOctave = 4): number | null {\n const semi = svaraSemitone(note);\n if (semi === null || note.svara === undefined) return null;\n const [octave] = note.svara;\n return (baseOctave + 1 + OCTAVE_OFFSET[octave]) * 12 + tonicPc + semi;\n}\n\n/** MIDI of a কণ/রেশ grace: one pitch per grace svara, in written order.\n * Goes through `svaraToMidi`, so a komal/tivra grace sounds as written (the\n * legacy tuple form carries no accidentals and is shuddha by construction). */\nexport function graceMidis(\n grace: Note['kan'],\n tonicPc: number,\n baseOctave = 4,\n): number[] {\n return graceNotes(grace)\n .map((n) => svaraToMidi(n, tonicPc, baseOctave))\n .filter((m): m is number => m !== null);\n}\n\n/** MIDI → Tone note name (`C#4`). */\nexport function midiToSampleName(midi: number): string {\n const pc = ((midi % 12) + 12) % 12;\n const octave = Math.floor(midi / 12) - 1;\n return `${SHARP_NAMES[pc]}${octave}`;\n}\n\n/** MIDI → santoor sample filename stem (`cs4`): lowercase, `#` → `s`. */\nexport function sampleFileName(midi: number): string {\n return midiToSampleName(midi).toLowerCase().replace('#', 's');\n}\n\n/**\n * Logistic S-curve on [0, 1], normalised so f(0) = 0 and f(1) = 1.\n *\n * A মীড় is **not** a linear ramp. The hand (or the voice) accelerates away\n * from the source pitch and decelerates into the target — \"if the pull is too\n * fast, the melody loses its vocal quality; if it is too slow, the note dies\n * before reaching its destination\". That S shape is the established model for\n * portamento pitch contours (Yang & Chew's logistic fit, ISMIR 2016), and its\n * coefficient has a direct musical meaning: `steepness` is how abruptly the\n * pitch leaves one svara for the next.\n */\nexport function sCurve(x: number, steepness = 8): number {\n const t = Math.min(Math.max(x, 0), 1);\n const logistic = (u: number) => 1 / (1 + Math.exp(-steepness * (u - 0.5)));\n const lo = logistic(0);\n return (logistic(t) - lo) / (logistic(1) - lo);\n}\n","/**\n * লয় (laya) — the tempo tier a passage is sung at.\n *\n * Hindustani names the three tiers বিলম্বিত / মধ্য / দ্রুত (vilambit = slow,\n * madhya = medium, drut = fast), and Rabindrasangeet swaralipi uses the same\n * words: NLTR prints \"বিলম্বিত লয়:\" / \"দ্রুত লয়:\" at the head of the line\n * where the tempo changes (see `printedLay`).\n *\n * `meta.bpm` is the **দ্রুত** tempo — the fast one — so the tiers are\n * multipliers ≤ 1 on it and a document with no লয় marks plays exactly as it\n * did before this field existed.\n *\n * Zod-free on purpose: the viewer, player and creator import this directly\n * (the `spec/index.js` barrel would drag zod into their browser bundles — the\n * same rule as `taals.ts` and `grace.ts`).\n */\nimport type { Note, Row } from './schema.js';\n\nexport type Lay = 'drut' | 'madhya' | 'vilambit';\n\nexport const LAYS: readonly Lay[] = ['drut', 'madhya', 'vilambit'];\n\n/**\n * ### The tempo factors — change them HERE.\n *\n * Fraction of `meta.bpm` each tier is played at. Consumers override per\n * document (`meta.laySpeeds`) or per player/export call (`laySpeeds`), so\n * these are only the fallback.\n */\nexport const LAY_SPEEDS: Record<Lay, number> = {\n drut: 1,\n madhya: 0.75,\n vilambit: 0.5,\n};\n\nexport type LaySpeeds = Partial<Record<Lay, number>>;\n\n/** Resolve the factors actually in force: call option → document → default. */\nexport function resolveLaySpeeds(doc?: LaySpeeds, opt?: LaySpeeds): Record<Lay, number> {\n return { ...LAY_SPEEDS, ...doc, ...opt };\n}\n\n/**\n * The printed লয় mark: the leading lyric-only cells NLTR writes a tempo\n * change as (\"বিলম্বিত\" \"লয়:\"). Reading it means the 1738 already-converted\n * songs change tempo without being reconverted or edited.\n *\n * ponytail: matches the first word only, and only in the leading annotation\n * position where real lyrics never sit — so 'মধ্যমান' (a taal) can't trip it.\n * If a source ever writes the mark elsewhere in the row, give it `row.lay`.\n */\nconst PRINTED: Record<string, Lay> = { দ্রুত: 'drut', মধ্য: 'madhya', বিলম্বিত: 'vilambit' };\n\nexport function printedLay(notes: Note[]): Lay | undefined {\n const first = notes[0];\n if (first === undefined || first.lyric === undefined) return undefined;\n for (const k of Object.keys(first)) if (k !== 'lyric') return undefined;\n return PRINTED[first.lyric.normalize('NFC')];\n}\n\n/** The লয় this row switches to, if any: the explicit field wins over the\n * source's printed mark. `undefined` = carry on at the previous tier. */\nexport function rowLay(row: Row): Lay | undefined {\n return row.lay ?? printedLay(row.notes);\n}\n","/**\n * Where in the song's text each note sings, and which notes sing a stretch of it.\n *\n * A swaralipi's lyric row is phonetic and split into syllables (আ|বা|র্, চি|ৎ|ত,\n * ৹ for a held syllable), and it often writes a refrain out again. So the\n * notation's letters are aligned to the text by global alignment\n * (Needleman–Wunsch) that may also jump to any word start, the way JumpDTW lets\n * a score re-enter its own repeat blocks (Fremerey, Müller & Clausen, ISMIR\n * 2010). Over gitabitan's 1827 song/notation pairs it aligns 97.9 % of the\n * notation's letters; the rest are songs whose text is only a fragment.\n */\nimport type { Swaralipi } from '../spec/schema.js';\nimport type { Visit } from './repeats.js';\nimport type { PlayEvent } from './schedule.js';\n\n/** `part.row.note` → the `[start, end)` UTF-16 offsets of the text it sings. */\nexport type LyricMap = Map<string, [number, number]>;\n\n/** The text's lines as the events sing them, each word timed by its first note — an LRC's\n * cues. A line sung again (a repeat) is a new cue. Words are the text's whitespace runs. */\nexport function lyricCues(\n events: PlayEvent[],\n map: LyricMap,\n text: string,\n): { beat: number; words: { beat: number; text: string }[] }[] {\n const tokens = [...text.matchAll(/\\S+/g)].map((m) => ({\n text: m[0],\n start: m.index,\n end: m.index + m[0].length,\n line: text.slice(0, m.index).split('\\n').length - 1,\n }));\n const cues: { beat: number; line: number; last: number; words: { beat: number; text: string }[] }[] = [];\n for (const ev of events) {\n const span = map.get(ev.path);\n const index = span ? tokens.findIndex((t) => t.start <= span[0] && span[0] < t.end) : -1;\n if (index < 0) continue;\n const token = tokens[index]!;\n let cue = cues.at(-1);\n if (!cue || cue.line !== token.line || index < cue.last) {\n cue = { beat: ev.beat, line: token.line, last: -1, words: [] };\n cues.push(cue);\n }\n if (index !== cue.last) {\n cue.words.push({ beat: ev.beat, text: token.text });\n cue.last = index;\n }\n }\n return cues.map(({ beat, words }) => ({ beat, words }));\n}\n\n/** Play only the notes singing these `[start, end)` stretches of the text, in order. */\nexport interface Excerpt {\n lyrics: LyricMap;\n ranges: [number, number][];\n}\n\nconst MATCH = 2;\nconst GAP = 1;\nconst JUMP = 4;\nconst RUN = 3;\n// 98 % of the corpus's misspelt syllables run under 8 unplaced letters.\nconst STRAY = 8;\nconst EPS = 1e-6;\nconst [DIAG, UP, LEFT, JUMPED] = [1, 2, 3, 4];\n\n/** The letters two spellings share: virama, nukta and ৹ dropped, খণ্ড ত read as ত. */\nconst letters = (s: string): string =>\n s\n .normalize('NFD')\n .replace(/ৎ/g, 'ত')\n .replace(/[^\\p{L}\\p{M}]|[়্]/gu, '')\n .toLowerCase();\n\n/** Each note of `doc` that sings a letter of `text`, with the stretch of `text` it sings. */\nexport function alignLyrics(doc: Swaralipi, text: string): LyricMap {\n const sung: { letter: string; path: string }[] = [];\n doc.parts.forEach((part, p) =>\n part.rows.forEach((row, r) =>\n row.notes.forEach((note, i) => {\n for (const letter of letters(note.lyric ?? '')) sung.push({ letter, path: `${p}.${r}.${i}` });\n }),\n ),\n );\n const said: { letter: string; from: number; to: number }[] = [];\n const starts: number[] = [];\n let at = 0;\n let gap = true;\n for (const ch of text) {\n const ls = letters(ch);\n if (ls === '') {\n gap ||= /[\\s\\p{P}]/u.test(ch);\n // A virama / nukta / joiner belongs to the letter before it, so a span never splits a conjunct's marks off.\n if (/[\\p{M}\\p{Cf}]/u.test(ch) && said.at(-1)?.to === at) said.at(-1)!.to += ch.length;\n } else {\n if (gap) starts.push(said.length);\n gap = false;\n }\n for (const letter of ls) said.push({ letter, from: at, to: at + ch.length });\n at += ch.length;\n }\n\n const n = sung.length;\n const m = said.length;\n const w = m + 1;\n const from = new Uint8Array((n + 1) * w);\n const best = new Int32Array(n + 1);\n // Before any letter is sung the text starts at its top; anywhere else costs a jump.\n let prev = new Int32Array(w).fill(-(2 ** 30));\n prev[0] = 0;\n let cur = new Int32Array(w);\n /** Jump from the row's best cell to every word start, then let the row skip text letters. */\n const settle = (i: number, row: Int32Array): void => {\n for (let j = 1; j < w; j++) if (row[j]! > row[best[i]!]!) best[i] = j;\n for (const s of starts) {\n if (row[best[i]!]! - JUMP > row[s]!) {\n row[s] = row[best[i]!]! - JUMP;\n from[i * w + s] = JUMPED;\n }\n }\n for (let j = 1; j < w; j++) {\n if (row[j - 1]! - GAP > row[j]!) {\n row[j] = row[j - 1]! - GAP;\n from[i * w + j] = LEFT;\n }\n }\n };\n settle(0, prev);\n for (let i = 1; i <= n; i++) {\n cur[0] = prev[0]! - GAP;\n from[i * w] = UP;\n for (let j = 1; j < w; j++) {\n const diag = prev[j - 1]! + (sung[i - 1]!.letter === said[j - 1]!.letter ? MATCH : -GAP);\n const up = prev[j]! - GAP;\n cur[j] = Math.max(diag, up);\n from[i * w + j] = diag >= up ? DIAG : UP;\n }\n best[i] = 0;\n settle(i, cur);\n [prev, cur] = [cur, prev];\n }\n\n // Trace back from the best end, collecting the letters that agree.\n const pairs: [number, number][] = [];\n let j = 0;\n for (let k = 1; k < w; k++) if (prev[k]! > prev[j]!) j = k;\n for (let i = n; i > 0; ) {\n const step = from[i * w + j];\n if (step === JUMPED) j = best[i]!;\n else if (step === LEFT) j--;\n else if (step === UP) i--;\n else {\n if (sung[i - 1]!.letter === said[j - 1]!.letter) pairs.push([i - 1, j - 1]);\n i--;\n j--;\n }\n }\n pairs.reverse();\n // A lone agreeing letter (a vowel sign past the text's end) is chance, not\n // the same word: only RUN sung letters agreeing in a row place a note. A row\n // carries on into the text's next letter, or across a jump to a word start,\n // so a short word sung over and over (আয়্ আয়্) holds.\n const wordStart = new Set(starts);\n const follows = (k: number): boolean =>\n pairs[k]![0] === pairs[k - 1]![0] + 1 && (pairs[k]![1] === pairs[k - 1]![1] + 1 || wordStart.has(pairs[k]![1]));\n const out: LyricMap = new Map();\n /** The text letter each note's span ends on: a syllable grows only by the letter after it. */\n const last = new Map<string, number>();\n for (let a = 0, b = 1; a < pairs.length; a = b++) {\n while (b < pairs.length && follows(b)) b++;\n if (b - a < RUN) continue;\n for (const [s, t] of pairs.slice(a, b)) {\n const { path } = sung[s]!;\n const { from: lo, to: hi } = said[t]!;\n const span = out.get(path);\n if (span === undefined) out.set(path, [lo, hi]);\n else if (t === last.get(path)! + 1) span[1] = hi;\n else continue;\n last.set(path, t);\n }\n }\n return out;\n}\n\nconst mod = (a: number, n: number): number => ((a % n) + n) % n;\nconst sings = (v: Visit): boolean => v.note.svara !== undefined || v.note.sustain === true;\n\n/**\n * The visits of `order` that sing `excerpt`, and the matra (in `at`, each\n * visit's written matra in the whole song) the first one starts on.\n *\n * Each range plays the song's form while its words stay inside the range — a\n * `{ }` repeat, a return to the asthayi — from its first sung note to the last\n * one before the words leave it. Rests and held syllables go with it; a range\n * the notation does not sing is left out. Between two ranges a rest keeps the\n * next one on the beat it has in the whole song, so the taal never breaks.\n */\nexport function excerptVisits(\n order: Visit[],\n at: number[],\n { lyrics, ranges }: Excerpt,\n cycle: (v: Visit) => number | undefined,\n): { visits: Visit[]; matra: number } {\n // Where each visit sings in the text; -1 for words the text does not have\n // (another stanza, another song): a stretch of STRAY or more letters the\n // alignment left unplaced. A shorter one is a syllable spelt otherwise.\n const pos = order.map((v) => lyrics.get(`${v.p}.${v.r}.${v.i}`)?.[0]);\n for (let a = 0; a < order.length; a++) {\n if (pos[a] !== undefined || letters(order[a]!.note.lyric ?? '') === '') continue;\n let b = a;\n let stray = 0;\n while (b < order.length && pos[b] === undefined) stray += letters(order[b++]!.note.lyric ?? '').length;\n if (stray >= STRAY) pos.fill(-1, a, b);\n a = b;\n }\n\n const visits: Visit[] = [];\n let first: number | undefined;\n let end = 0;\n for (const [lo, hi] of ranges) {\n const inside = (k: number): boolean | undefined => (pos[k] === undefined ? undefined : pos[k]! >= lo && pos[k]! < hi);\n const a = order.findIndex((_, k) => inside(k) === true);\n if (a < 0) continue;\n let b = a + 1;\n while (b < order.length && inside(b) !== false) b++;\n while (b - 1 > a && !sings(order[b - 1]!)) b--;\n const n = cycle(order[a]!);\n if (first === undefined) first = a;\n else if (n !== undefined) {\n // ponytail: phase is the whole song's matra mod this taal's cycle, so a jump across a তালফেরতা change is approximate.\n const gap = mod(at[a]! - at[end]!, n);\n if (gap > EPS) visits.push({ ...order[end - 1]!, note: { rest: true, durationMatra: gap } });\n }\n visits.push(...order.slice(a, b));\n end = b;\n }\n return { visits, matra: first === undefined ? 0 : at[first]! };\n}\n","/**\n * The Swarabitan ASCII codec: decode one grid-cell text into spec `Note`s.\n *\n * NLTR renders notation through the legacy \"Swarabitan\" webfont, which maps\n * ASCII to akarmatrik glyphs. The table below was derived by dumping every\n * glyph of `Swarabitan.woff` (tools/font-dump/) and cross-checking against\n * the Swarabitan legend scans, the rendered reference screenshot of song\n * 4270, and corpus-wide token statistics. Evidence per assignment:\n *\n * Letters (full-size glyphs):\n * s=স r=র g=গ m=ম p=প q=ধ n=ন — the seven shuddha letters\n * d=দ (komal dha) t=জ্ঞ (komal ga) — legend: কোমল র—ঋ, কোমল গ—জ্ঞ,\n * k=ক্ষ (tivra ma) u=ণ (komal ni) — কড়ি ম—ক্ষ, কোমল ধ—দ, কোমল ন—ণ\n * v=ঋ (komal re)\n * Modifiers:\n * f = রেফ above → taar octave (zero-width high combining mark)\n * h = হসন্ত below → mandra octave (low combining mark; corpus nh/uh/dh/ph)\n * leading '-' = no new vowel attack (melisma; lyric row shows ৹)\n * trailing 'a' = the আ-কার matra carrier; k letter-units in one cell\n * share it → k notes of 1/k matra each\n * UPPERCASE letter = small raised form = কণ (kan/grace) prefix; takes its\n * own f/h (corpus: Sfua, NHsa, QHpha); width ratios ~0.65\n * confirm uppercase↔lowercase pairing\n * Structurals (own cells):\n * A = thin full-height bar → দাঁড়ি vibhag separator (fixed columns)\n * l = serif danda I → cycle end; ll / single-glyph L = section\n * %=সা &=নি — precomposed one-matra forms (rare)\n * Known-but-kept-raw marks (drawn pieces the spec doesn't model yet):\n * w x = left/right ends of a long under-arc; E J j y $ < > = _ = arc/line\n * fill segments; | = thin yugal-dari stop mark (mostly annotation rows);\n * digits/!/@ (+f/F sam tick) = taal beat labels; b=× o O e ` + , . i : ;\n * = dots/ticks/duration marks; B C * ^ ~ c = rare precomposed/legacy forms.\n *\n * Decoding never throws: any chunk outside the grammar becomes a raw-only\n * note and is reported as unknown — zero data loss by construction.\n */\nimport type { Note, Octave, Svara, SvaraLetter } from '../spec/index.js';\n\nexport interface CellDecode {\n notes: Note[];\n /** Chunks that failed the grammar (reported, kept as raw notes). */\n unknownTokens: string[];\n /** Chunks understood but intentionally left raw (marks, beat labels …). */\n knownRawTokens: string[];\n /** True if at least one chunk decoded to a semantic note. */\n decoded: boolean;\n}\n\ninterface LetterDef {\n letter: SvaraLetter;\n komal?: true;\n tivra?: true;\n}\n\n/** ASCII → svara letter (+ komal/tivra). The five non-shuddha glyph letters\n * are distinct characters in akarmatrik, so the flags live here. */\nconst LETTERS: Record<string, LetterDef> = {\n s: { letter: 's' },\n r: { letter: 'r' },\n g: { letter: 'g' },\n m: { letter: 'm' },\n p: { letter: 'p' },\n q: { letter: 'd' }, // ধ — shuddha dha\n n: { letter: 'n' },\n d: { letter: 'd', komal: true }, // দ\n t: { letter: 'g', komal: true }, // জ্ঞ\n k: { letter: 'm', tivra: true }, // ক্ষ\n u: { letter: 'n', komal: true }, // ণ\n v: { letter: 'r', komal: true }, // ঋ\n};\n\n/** Standalone structural tokens (bars are handled by the bar-run rule). */\nconst STRUCTURALS: Record<string, () => Note> = {\n '%': () => ({ svara: ['madhyam', 's'] }), // precomposed সা\n '&': () => ({ svara: ['madhyam', 'n'] }), // precomposed নি\n};\n\n/**\n * Bar/bracket runs: `l`(I danda) `ll`/`L`(II) `llll`/`LL`(IIII) `A`(দাঁড়ি),\n * plus composites the corpus writes into one cell — `l[]l` / `L[]L` (the\n * legend's \"I [ ] I\" return-to-asthayi-with-changed-notes marker), `AA`,\n * and `-A` (the previous note's continuation dash sharing the dari's cell).\n */\nconst BAR_RUN_RE = /^(-)?([lLA[\\]]+)$/;\n\nfunction decodeBarRun(body: string): Note[] | undefined {\n const m = body.match(BAR_RUN_RE);\n if (!m || !/[lLA]/.test(m[2]!)) return undefined;\n const notes: Note[] = [];\n if (m[1]) notes.push({ sustain: true });\n const run = m[2]!;\n let i = 0;\n while (i < run.length) {\n const ch = run[i]!;\n if (ch === 'l' || ch === 'L') {\n let j = i;\n while (j < run.length && run[j] === ch) j++;\n const strokes = (j - i) * (ch === 'L' ? 2 : 1);\n notes.push({ bar: strokes >= 4 ? 'quad' : strokes >= 2 ? 'double' : 'single' });\n i = j;\n } else if (ch === 'A') {\n notes.push({ bar: 'dari' });\n i++;\n } else {\n notes.push({ brackets: [{ kind: 'alt', edge: ch === '[' ? 'open' : 'close' }] });\n i++;\n }\n }\n return notes;\n}\n\n/** Marks/labels that are understood but deliberately preserved raw-only. */\nconst KNOWN_RAW_RE = [\n /^[wxyjEJ$<>=_]+$/, // arc & line drawing segments\n /^\\|+$/, // thin yugal-dari stop mark\n /^[0-9!@#]{1,2}[fF]?:?$/, // beat-number labels incl. 10–16 (sam tick = f/F, e.g. 1f / 1F / 2:)\n /^[oOe`+,.;:iI~^*bcBCWXYFHZz'\"?]$/, // dots, ticks, duration marks, legacy forms\n];\n\nconst OPEN_BRACKETS: Record<string, 'repeat' | 'skip' | 'alt'> = {\n '{': 'repeat',\n '(': 'skip',\n '[': 'alt',\n};\nconst CLOSE_BRACKETS: Record<string, 'repeat' | 'skip' | 'alt'> = {\n '}': 'repeat',\n ')': 'skip',\n ']': 'alt',\n};\n\nfunction octaveOf(mark: string | undefined): Octave {\n if (mark === 'f' || mark === 'F') return 'taar';\n if (mark === 'h' || mark === 'H') return 'mandra';\n return 'madhyam';\n}\n\n/**\n * Body grammar of one chunk (brackets already peeled):\n *\n * [beat-digit] ['-'] [KAN] unit* ['a'] [fh] [i:] [KAN] [beat-digit]\n *\n * where unit = letter [fh] and KAN = uppercase letter [fFhH]. Corpus\n * realities beyond the canonical `[-]KAN unit+ a` shape:\n * - octave mark typed after the আ-কার: `saf` ≡ `sfa` (taar sa) — the reph\n * applies to the last unit;\n * - trailing `i` (two stacked rings, ঃ-shaped) or `:` (two lozenges — a\n * different glyph) after the matra: a **matra sign worth ½**, the আ-কার's\n * half-brother (legend `রাঃ` = 1½, `সঃ` = ½; corpus rows fit their taal\n * cycle 114:19 in favour of that reading over \"articulation only\"). The\n * durations below still ignore it — they split the cell evenly among its\n * units, so `qinqi` decodes ⅓⅓⅓ where the sheet says ½ ¼ ¼. The viewer\n * reads the marks off `raw` and draws them right (viewer/render.ts\n * `rawMarks`); playback is what the even split still gets wrong;\n * - trailing KAN (`-aR`): an anticipatory grace drawn at the cell's right\n * edge, leading into the next note — attached to this cell's last note;\n * - the cut mark may also lead or sit between units (`-iqi`, `mpimi`);\n * - leading `z` = blank spacer glyph (empty outline in the font) — skipped.\n * A standalone detached `a` (no hyphen) is a 1-matra rest per the legend\n * (\"হাইফেন-বর্জিত … বিরামের মাত্রা\").\n */\nconst BODY_RE =\n /^([0-9!@][fF]?)?([zj]*)(-)?([i:])?(?:([SRGMPQNDTKUV])([fFhH])?)?((?:[srgmpqndtkuv][fh]?[i:]?)+)?(a)?([fh])?([i:])?(?:([SRGMPQNDTKUV])([fFhH])?)?([0-9!@][fF]?)?(-)?$/;\n\nfunction decodeChunk(chunk: string): { notes: Note[]; kind: 'decoded' | 'known' | 'unknown' } {\n // 1. Peel brackets.\n const opens: ('repeat' | 'skip' | 'alt')[] = [];\n const closes: ('repeat' | 'skip' | 'alt')[] = [];\n let body = chunk;\n while (body.length > 0) {\n const kind = OPEN_BRACKETS[body[0]!];\n if (kind === undefined) break;\n opens.push(kind);\n body = body.slice(1);\n }\n while (body.length > 0) {\n const kind = CLOSE_BRACKETS[body[body.length - 1]!];\n if (kind === undefined) break;\n closes.unshift(kind);\n body = body.slice(0, -1);\n }\n\n const finish = (notes: Note[], kind: 'decoded' | 'known' | 'unknown') => {\n if (notes.length === 0) notes.push({});\n const first = notes[0]!;\n const last = notes[notes.length - 1]!;\n if (opens.length > 0) first.brackets = [...opens.map((kind_) => ({ kind: kind_, edge: 'open' as const })), ...(first.brackets ?? [])];\n if (closes.length > 0) last.brackets = [...(last.brackets ?? []), ...closes.map((kind_) => ({ kind: kind_, edge: 'close' as const }))];\n return { notes, kind };\n };\n\n // 2. Bracket-only chunk → raw carrier for the bracket edges.\n if (body === '') return finish([{}], 'decoded');\n\n // 3. Bar/bracket runs, then the remaining standalone structurals.\n const barRun = decodeBarRun(body);\n if (barRun) return finish(barRun, 'decoded');\n const structural = STRUCTURALS[body];\n if (structural) return finish([structural()], 'decoded');\n\n // 4. Known raw marks.\n if (KNOWN_RAW_RE.some((re) => re.test(body))) return finish([{}], 'known');\n\n // 5. Note grammar.\n const m = body.match(BODY_RE);\n if (m) {\n const [, , , hyphen, , kanLetter, kanOct, unitsStr, aakar, postOct, , trailKan, trailKanOct] = m;\n const attachKan = (note: Note, letter: string, oct: string | undefined) => {\n const def = LETTERS[letter.toLowerCase()]!;\n // NOTE: the spec kan is a plain [octave, letter] tuple, so a komal\n // kan letter (e.g. D = small দ) is projected onto its shuddha\n // letter; the exact glyph stays recoverable from `raw`.\n note.kan = [octaveOf(oct?.toLowerCase()), def.letter] as Svara;\n };\n if (unitsStr) {\n const units = unitsStr.match(/[srgmpqndtkuv][fh]?/g) ?? [];\n const notes: Note[] = units.map((unit) => {\n const def = LETTERS[unit[0]!]!;\n const note: Note = { svara: [octaveOf(unit[1]), def.letter] as Svara };\n if (def.komal) note.komal = true;\n if (def.tivra) note.tivra = true;\n if (units.length > 1) note.durationMatra = 1 / units.length;\n return note;\n });\n const last = notes[notes.length - 1]!;\n // Post-আকার octave mark (`saf`): applies to the last unit unless it\n // already carries its own mark.\n if (postOct && last.svara![0] === 'madhyam') {\n last.svara = [octaveOf(postOct), last.svara![1]] as Svara;\n }\n if (hyphen) notes[0]!.sustain = true;\n if (kanLetter) attachKan(notes[0]!, kanLetter, kanOct);\n if (trailKan && last.kan === undefined) attachKan(last, trailKan, trailKanOct);\n return finish(notes, 'decoded');\n }\n if (aakar) {\n // '-a' = sustain (hold previous pitch, no new attack);\n // bare detached 'a' = one-matra rest (legend: hyphen-less matra sign).\n const note: Note = hyphen ? { sustain: true } : { rest: true };\n if (trailKan) attachKan(note, trailKan, trailKanOct);\n else if (kanLetter) attachKan(note, kanLetter, kanOct);\n return finish([note], 'decoded');\n }\n if (hyphen && !kanLetter && !trailKan) {\n // A bare continuation dash (`-`, `-i`) — the আ-কার is implied.\n return finish([{ sustain: true }], 'decoded');\n }\n // Kan without units, or digit-edges with no note between — keep raw.\n }\n\n return finish([{}], 'unknown');\n}\n\n/**\n * Decode one cell's text. Multi-chunk cells (whitespace-separated) emit\n * notes in order; the first note of each chunk carries that chunk's source\n * text in `raw`, so joining a cell's `raw` values with spaces reproduces\n * the normalized cell text (the lossless property tests rely on this).\n */\nexport function decodeCell(text: string): CellDecode {\n const chunks = text.split(/\\s+/).filter((c) => c.length > 0);\n const out: CellDecode = { notes: [], unknownTokens: [], knownRawTokens: [], decoded: false };\n for (const chunk of chunks) {\n const { notes, kind } = decodeChunk(chunk);\n notes[0]!.raw = chunk;\n if (kind === 'decoded') out.decoded = true;\n else if (kind === 'known') out.knownRawTokens.push(chunk);\n else out.unknownTokens.push(chunk);\n out.notes.push(...notes);\n }\n return out;\n}\n","/**\n * The order a swaralipi is **sung** in, as opposed to the order it is written.\n * Swarabitan's legend (স্বরবিতান pp. ১৩৫–১৩৬, gitabitan.io/bn/swaralipi/how-to-read/):\n *\n * - `{ }` is sung twice; `( )` inside it is left out the second time, and the\n * `[ ]` notes written above stand in for the notes under them.\n * - II at a kali's end sends the singer back to the asthayi's opening II, on\n * to the ‖ stop mark, then into the next kali: D.S. al Fine, with ‖ as the\n * Fine. I[ ]I / II[ ]II make that return sing the `[ ]` notes.\n * - IIII written as one stroke group ends the song: no return.\n *\n * The notation is written for this order, so every jump lands where the grid\n * expects it: the \"৹ ৹ ৹\" after a kali-end II is the rest of the cycle the ‖\n * broke off, which is what keeps a looping tabla on sam. Whatever the marks\n * leave unsaid (no ‖, a stray bracket) is sung as written.\n */\nimport { decodeCell } from '../convert/codec.js';\nimport type { Bracket, Note, Swaralipi } from '../spec/schema.js';\n\n/** One note as sung: where it is written (for highlights) and what sounds. */\nexport interface Visit {\n p: number;\n r: number;\n i: number;\n /** The written note, or a `[ ]` note standing in for it on a repeat. */\n note: Note;\n}\n\n/**\n * A raw the codec could not decode but which still **holds a matra** in the\n * source grid: it carries svara letters or the আ-কার carrier `a` (e.g. a\n * mistyped `` `-a `` / `frsfa` / `PUda`). Bracket, bar-glyph and beat-label\n * carriers contain none of these, so they stay timeless. Dropping these\n * columns outright ran the melody ahead of the তাল from that point on.\n */\nconst UNDECODED_CELL = /[srgmpqnvtduka]/i;\n\n/** A column that produces no sound and no time advance (bar, bracket-only,\n * carrier, structural raw). Mirrors the viewer's non-pitched, non-rest\n * classes. */\nexport const isSilent = (n: Note): boolean =>\n n.svara === undefined &&\n n.rest !== true &&\n n.sustain !== true &&\n !(n.raw !== undefined && UNDECODED_CELL.test(n.raw));\n\n/** ‖ written above a note: অবসানের চিহ্ন, where a return to the asthayi stops. */\nconst STOP_MARK = /^\\|+$/;\nconst EPS = 1e-6;\n\ninterface Token extends Visit {\n timed: boolean;\n}\n\nconst edges = (n: Note, kind: Bracket['kind'], edge: Bracket['edge']): number =>\n n.brackets?.filter((b) => b.kind === kind && b.edge === edge).length ?? 0;\nconst sounds = (n: Note): boolean => n.svara !== undefined || n.rest === true || n.sustain === true;\nconst matra = (notes: Note[]): number => notes.reduce((sum, n) => sum + (n.durationMatra ?? 1), 0);\n\n/** Every note of `doc` in the order it is sung. */\nexport function playOrder(doc: Swaralipi): Visit[] {\n const tokens: Token[] = [];\n doc.parts.forEach((part, p) =>\n part.rows.forEach((row, r) =>\n row.notes.forEach((note, i) => tokens.push({ p, r, i, note, timed: note.bar === undefined && !isSilent(note) })),\n ),\n );\n const { asthayi, stop, returns } = form(tokens);\n const changed = changedNotes(tokens);\n const out: Visit[] = [];\n // The token of the last note sung.\n let last = -1;\n\n /** Sing tokens lo..hi-1: each `{ }` twice, its `( )` only the first time. */\n const sing = (lo: number, hi: number, useChanged: boolean): void => {\n const repeats: { open: number; again: boolean }[] = [];\n // Matra of written notes a longer `[ ]` note already sang over.\n let owed = 0;\n for (let k = lo; k < hi; ) {\n const t = tokens[k]!;\n if (edges(t.note, 'repeat', 'open') > 0 && repeats.at(-1)?.open !== k) repeats.push({ open: k, again: false });\n const again = repeats.at(-1)?.again === true;\n const skipTo = again && edges(t.note, 'skip', 'open') > 0 ? skipEnd(tokens, k, hi) : -1;\n if (skipTo >= 0) {\n if (edges(tokens[skipTo]!.note, 'repeat', 'close') > 0) repeats.pop();\n k = skipTo + 1;\n owed = 0;\n continue;\n }\n if (owed > EPS && t.timed) owed -= matra([t.note]);\n else {\n const sub = useChanged || again ? changed.get(k) : undefined;\n // A `[ ]` note shorter than the one it replaces would pull the melody off sam.\n const fits = sub !== undefined && matra(sub) >= matra([t.note]) - EPS;\n for (const note of fits ? sub : [t.note]) out.push({ p: t.p, r: t.r, i: t.i, note });\n if (t.timed) last = k;\n owed = fits ? matra(sub) - matra([t.note]) : 0;\n }\n const loop = edges(t.note, 'repeat', 'close') > 0 ? repeats.at(-1) : undefined;\n if (loop !== undefined && !loop.again) {\n loop.again = true;\n k = loop.open;\n owed = 0;\n continue;\n }\n if (loop !== undefined) repeats.pop();\n k++;\n }\n };\n\n let from = 0;\n for (const ret of returns) {\n sing(from, ret.resume, false);\n // Singing that already stopped at ‖ \"takes up another kali\" there: a ‖ at\n // the asthayi's own close, or a `{ }` whose second pass skips from ‖ to `}`.\n if (last !== stop) sing(asthayi, stop + 1, ret.changed);\n from = ret.resume;\n }\n sing(from, tokens.length, false);\n return out;\n}\n\n/**\n * The song's form: where the asthayi starts (its opening II, else the top),\n * where a return stops (the first ‖ in the asthayi), and the token after each\n * kali-end II or I[ ]I. No ‖ → no returns: the notation then does not say how\n * far back to sing.\n */\nfunction form(tokens: Token[]): { asthayi: number; stop: number; returns: { resume: number; changed: boolean }[] } {\n // A II opens a kali when its row's singing comes after it, and closes one\n // when the singing comes before; mid-row, it alternates with the last II.\n const first = new Map<string, number>();\n const last = new Map<string, number>();\n tokens.forEach((t, k) => {\n if (!t.timed) return;\n const row = `${t.p}.${t.r}`;\n if (!first.has(row)) first.set(row, k);\n last.set(row, k);\n });\n const opens: number[] = [];\n let opening = false;\n tokens.forEach((t, k) => {\n if (t.note.bar !== 'double') return;\n const row = `${t.p}.${t.r}`;\n const before = (first.get(row) ?? Infinity) < k;\n const after = (last.get(row) ?? -1) > k;\n opening = before !== after ? after : !opening;\n if (opening) opens.push(k);\n });\n\n // A kali ends on a closing II, or on I[ ]I / II[ ]II (an empty `[ ]` among\n // the bars); a run of bars holding IIII ends the song instead.\n const returns: { resume: number; changed: boolean }[] = [];\n for (let k = 0; k < tokens.length; k++) {\n let at = -1;\n let open = false;\n let changed = false;\n let end = false;\n for (; k < tokens.length && !tokens[k]!.timed; k++) {\n const n = tokens[k]!.note;\n if (n.bar === 'quad') end = true;\n if (n.bar === 'double' && !opens.includes(k)) at = k;\n if (edges(n, 'alt', 'open') > 0) open = true;\n if (open && edges(n, 'alt', 'close') > 0) {\n at = k;\n changed = true;\n }\n }\n if (at >= 0 && !end) returns.push({ resume: at + 1, changed });\n }\n\n const top = opens[0];\n const asthayi = top !== undefined && top < (returns[0]?.resume ?? Infinity) ? top : 0;\n // The asthayi ends at its own closing II, or where the next kali opens. A ‖\n // with nothing sung after it is the song's own end (\"এইখানে একেবারে থামিবে\"),\n // not where a return stops.\n const asthayiEnd = Math.min(returns[0]?.resume ?? Infinity, opens.find((k) => k > asthayi) ?? Infinity, tokens.length);\n const lastSung = tokens.reduce((last, t, k) => (t.timed ? k : last), -1);\n const stop = tokens.findIndex(\n (t, k) =>\n k >= asthayi && k < asthayiEnd && k < lastSung && t.note.above?.some((a) => STOP_MARK.test(a.raw ?? '')) === true,\n );\n return { asthayi, stop, returns: stop < 0 ? [] : returns };\n}\n\n/**\n * The `[ ]` notes written above each column, by token: what is sung there on\n * a repeat. A span runs from the above-row `[` to its `]`; a column under it\n * with nothing above keeps its own note.\n */\nfunction changedNotes(tokens: Token[]): Map<number, Note[]> {\n const out = new Map<number, Note[]>();\n let row = '';\n let inside = false;\n tokens.forEach((t, k) => {\n // ponytail: a span is closed at the row's end — no corpus span crosses a row.\n if (row !== `${t.p}.${t.r}`) {\n row = `${t.p}.${t.r}`;\n inside = false;\n }\n const notes: Note[] = [];\n for (const above of t.note.above ?? []) {\n // An older converter left a few cells like `[sfa]` undecoded: read them as it now would.\n const read = above.raw !== undefined && !sounds(above) && above.brackets === undefined;\n for (const a of read ? decodeCell(above.raw!).notes : [above]) {\n if (edges(a, 'alt', 'open') > 0) inside = true;\n if (inside && sounds(a)) notes.push(a);\n if (edges(a, 'alt', 'close') > 0) inside = false;\n }\n }\n if (notes.length > 0) out.set(k, notes);\n });\n return out;\n}\n\n/** The token closing the `( )` that opens at `k`, or -1 if it never closes. */\nfunction skipEnd(tokens: Token[], k: number, hi: number): number {\n for (let depth = 0, j = k; j < hi; j++) {\n depth += edges(tokens[j]!.note, 'skip', 'open') - edges(tokens[j]!.note, 'skip', 'close');\n if (depth <= 0) return j;\n }\n return -1;\n}\n","/**\n * Pure spec-doc → playback timeline. No Tone, no audio — the player turns\n * this `Schedule` into Transport events, but it is fully unit-testable on its\n * own and mirrors the viewer's spec-driven (not raw-driven) reading.\n *\n * Timing unit is the মাত্রা (matra / beat). One global beat cursor runs across\n * every part and row: NLTR \"systems\" (rows) are wraps of one continuous line,\n * and parts (asthayi → antara …) play back-to-back, so the music never pauses\n * at a row or part boundary.\n *\n * Each audible column carries the same `data-note` path the viewer emits\n * (`part.row.note`, note = absolute index into `row.notes`; see\n * src/viewer/render.ts), so `SwaralipiPlayer` can drive `highlight()` directly.\n */\nimport type { Note, Swaralipi, Taal } from '../spec/index.js';\nimport { resolveLaySpeeds, rowLay, type Lay, type LaySpeeds } from '../spec/lay.js';\nimport { sameTaal } from '../spec/taals.js';\nimport { graceMidis, parseTonic, svaraToMidi } from './pitch.js';\nimport { excerptVisits, type Excerpt } from './lyrics.js';\nimport { isSilent, playOrder } from './repeats.js';\n\nexport interface PlayEvent {\n /** Onset in matra from the start of the document. */\n beat: number;\n /** Ring length in matra (extended by following আ-কার holds). */\n durationBeats: number;\n /** Pitch as MIDI, or null for a rest / আ-কার hold column. */\n midi: number | null;\n /** MIDI of each কণ grace on this column, in written order (empty = none). */\n kan: number[];\n /** MIDI of each রেশ grace on this column, in written order (empty = none). */\n resh: number[];\n /** `part.row.note` highlight path. */\n path: string;\n kind: 'note' | 'rest' | 'sustain';\n /**\n * মীড়: this pitch is reached by **gliding** from the previous pitched event,\n * not by a new attack. The two (or more) notes are one continuous sound whose\n * pitch travels — see `meendContinuations`. Consumers pair an attack with its\n * targets via `glideTargets`.\n */\n glide?: true;\n}\n\n/**\n * One accompaniment stretch of the timeline: a লয় and a তাল held constant.\n * A new segment starts wherever either changes — they are independent marks.\n * `scale` is the fraction of the base bpm the passage sounds at, and it is\n * exactly the factor a looping accompaniment must change its own tempo by —\n * `beat` × secondsPerBeat gives its start in seconds. Always at least one\n * segment, the first at beat 0.\n */\nexport interface TempoSegment {\n /** Start, in schedule beats (see PlayEvent.beat). */\n beat: number;\n /** End, in schedule beats (= the next segment's start, or totalBeats). */\n endBeat: number;\n scale: number;\n lay: Lay;\n /** তাল in force: `meta.taal` until a row's `taal` changes it. `null` = an\n * explicit মুক্তছন্দ passage; `undefined` = the document names no taal. */\n taal?: Taal | null;\n}\n\nexport interface Schedule {\n events: PlayEvent[];\n /** Total length in matra (the cursor's final value). */\n totalBeats: number;\n /**\n * অনাগত/anacrusis: how far into its তাল cycle the song's first note falls, in\n * schedule beats — the count-in a rhythm plays when it leads (the player's\n * `countIn`), with the melody pushed this much later. Many songs begin\n * part-way through the cycle and sing a pickup before the সম. Found from the\n * notation's সম tick (`1f`/`2f`…), else, for a song that opens on loose notes,\n * from its bars (see loosePickupSam), against the opening taal's numBeats; 0\n * when the song starts on sam.\n */\n pickupBeats: number;\n /** Schedule beat of the song's first সম — where a rhythm that waits for the\n * singer comes in (the default). 0 when the song starts on sam. */\n samBeat: number;\n /** লয় / তাল stretches, in order and gapless. One entry (drut, scale 1,\n * `meta.taal`) for a document that never changes either — i.e. every\n * document written before `row.lay` / `row.taal` existed. */\n tempo: TempoSegment[];\n}\n\nexport interface ScheduleOptions {\n /** Tonic; accepts `C`, `C#`, `cs`… (see parseTonic). Default C. */\n tonic?: string;\n /** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */\n baseOctave?: number;\n /** Override the লয় tempo factors (see LAY_SPEEDS / meta.laySpeeds). */\n laySpeeds?: LaySpeeds;\n /** Apply লয় at all. Default true. The staff view sets it false: it reads\n * `durationBeats` as written note values, where a 0.75 stretch is not a\n * writable duration. */\n lay?: boolean;\n /** Sing the song's form (see playOrder): each `{ }` twice, `( )` only the\n * first time, the `[ ]` notes on the repeat, and back to the asthayi at each\n * kali's end. Default false — the written order, which the staff view and\n * anything grouping events by row rely on; the player and the audio/MIDI\n * exports turn it on. */\n repeats?: boolean;\n /** Play only the notes singing these stretches of the song's text (see\n * alignLyrics / excerptVisits). Taken from the order above. */\n excerpt?: Excerpt;\n}\n\n/**\n * Below-annotation raws that are মীড় arc drawing segments (codec known-raw):\n * `w`/`x` are the left/right curled ends, the rest are straight fill pieces.\n * Lives here rather than in the viewer because **both** need it and the viewer\n * may import the player (never the reverse — that would pull Tone into it).\n */\nexport const ARC_RAW_RE = /^[wWxXyYjJeEzZ$=_<>`\\\\]+$/;\nexport const isArcRaw = (raw: string | undefined): raw is string =>\n raw !== undefined && ARC_RAW_RE.test(raw);\n\n/** The spec's `meend` as the corpus's own arc marks; `both` = close, then re-open. */\nconst MEEND_MARKS: Record<NonNullable<Note['meend']>, string> = { start: 'w', end: 'x', both: 'xw' };\n\n/**\n * Note indices in one row that lie under a মীড় arc **without opening it** —\n * i.e. every note the pitch glides *to*, as opposed to the one it glides\n * *from*.\n *\n * Swarabitan's legend defines the under-arc as \"কোনো এক স্বর যখন আর এক স্বরে\n * বিশেষরূপে গড়াইয়া যায়\" — when one svara *rolls into* another (example:\n * ণা‿পা). It is one continuous phonation, which is why 90 % of the corpus's\n * 7 419 arcs end on a melisma (a note under the *same* held syllable, lyric ৹).\n * So the notes under an arc must not be re-articulated: only the first sounds.\n *\n * Two encodings feed the same scan — the converter's below-row `w`/`x` raws\n * (every meend in the 1738-song corpus) and the spec's own `meend: start|end`\n * (what the creator writes). A cell may carry both ends (`xw` =\n * close then re-open, `wx` = an arc drawn inside the one cell), so marks are\n * read **in order** — reading them as an unordered set left a `wx` arc open and\n * slurred the next eighteen notes into a single slide. Arcs are resolved per row — exactly one arc in the\n * whole corpus wraps across a row, so cross-row state would not pay for itself.\n */\nexport function meendContinuations(notes: Note[]): Set<number> {\n const out = new Set<number>();\n /** Notes seen since the arc opened — committed only once it closes. */\n let pending: number[] | undefined;\n notes.forEach((note, i) => {\n let marks = note.meend ? MEEND_MARKS[note.meend] : '';\n for (const b of note.below ?? []) if (isArcRaw(b.raw)) marks += b.raw;\n let marked = false;\n for (const ch of marks) {\n if (ch === 'x' || ch === 'X') {\n // Closes here: this note and everything since the open are targets.\n if (pending !== undefined) for (const k of [...pending, i]) out.add(k);\n pending = undefined;\n marked = true;\n } else if (ch === 'w' || ch === 'W') {\n pending = []; // opens here: this note is the source, not a target\n marked = true;\n }\n }\n if (!marked && pending !== undefined) pending.push(i);\n });\n // An arc left open at the row's end is a notation slip (5 in 1738 songs), not\n // a glide: committing it would slur the whole rest of the line into one\n // 16-beat slide. The viewer still draws it as a system-wrap continuation.\n return out;\n}\n\n/**\n * The glide targets belonging to the attack at `events[i]`: the pitched events\n * that follow it flagged `glide`. Silent columns (আ-কার holds) are transparent\n * — the note is still ringing through them — but a rest ends the phrase.\n * Consumers skip events that are themselves `glide` (already consumed here).\n */\nexport function glideTargets(events: PlayEvent[], i: number): PlayEvent[] {\n const out: PlayEvent[] = [];\n for (let j = i + 1; j < events.length; j++) {\n const ev = events[j]!;\n if (ev.kind === 'rest') break;\n if (ev.midi === null) continue;\n if (ev.glide !== true) break;\n out.push(ev);\n }\n return out;\n}\n\n/** Schedule beats between a grace and its column's start; consecutive graces step by it. */\nexport const GRACE_STEP = 0.12;\n\n/**\n * When each grace of `ev` sounds, in written order, mirrored around the\n * column's start: a কণ (written left of its svara) touches just before it, a\n * রেশ (written right) just after — so on a hold or rest column they touch under\n * whatever is still ringing. Not at the column's end: every grace is a fresh\n * strike, and one struck just before the next column is heard as its কণ.\n */\nexport function graceTouches(ev: PlayEvent): { midi: number; beat: number }[] {\n // ponytail: a fixed step, so several graces on a very short column spill past\n // it (two রেশ on a 1/5-matra note); scale the step by column length if needed.\n return [\n ...ev.kan.map((midi, g) => ({ midi, beat: ev.beat - GRACE_STEP * (ev.kan.length - g) })),\n ...ev.resh.map((midi, g) => ({ midi, beat: ev.beat + GRACE_STEP * (g + 1) })),\n ];\n}\n\n/**\n * One line of the sheet as the practice controls move by it: a `part.row`\n * with at least one timed column. It runs from its first event to the next\n * line's (the last one to `totalBeats`), so a line's trailing bars and holds\n * belong to it. A row sung twice (a repeat, a return to the asthayi) is two\n * lines with one `row`.\n */\nexport interface Line {\n /** `part.row` — the viewer's `data-row`. */\n row: string;\n /** Index of the line's first event. */\n first: number;\n beat: number;\n endBeat: number;\n}\n\nconst rowOf = (path: string): string => path.split('.').slice(0, 2).join('.');\nconst noteOf = (path: string): number => Number(path.split('.')[2] ?? 0);\n/** Written order of two `part.row` keys. */\nexport const byRow = (a: string, b: string): number => {\n const [ap = 0, ar = 0] = a.split('.').map(Number);\n const [bp = 0, br = 0] = b.split('.').map(Number);\n return ap - bp || ar - br;\n};\n\n/** The schedule's events grouped into sheet lines, in play order. A row of\n * bars and annotations only has no events, so it is not a line; a repeat that\n * jumps back within a row starts a new one. */\nexport function scheduleLines(schedule: Pick<Schedule, 'events' | 'totalBeats'>): Line[] {\n const lines: Line[] = [];\n let note = Infinity;\n schedule.events.forEach((ev, i) => {\n const n = noteOf(ev.path);\n if (lines.at(-1)?.row !== rowOf(ev.path) || n < note) lines.push({ row: rowOf(ev.path), first: i, beat: ev.beat, endBeat: 0 });\n note = n;\n });\n lines.forEach((line, k) => (line.endBeat = lines[k + 1]?.beat ?? schedule.totalBeats));\n return lines;\n}\n\n/** Index of the line holding event `i`. */\nexport function lineAt(lines: Line[], i: number): number {\n let k = 0;\n while (k + 1 < lines.length && lines[k + 1]!.first <= i) k++;\n return k;\n}\n\n/**\n * The line `path` (`part.row[.note]`) names — its own row, else the next row\n * that sounds — sung at the pass nearest line `near` (-1: the first pass).\n * -1 when no line is at or after it.\n */\nexport function lineFor(lines: Line[], path: string, near: number): number {\n let row: string | undefined;\n for (const line of lines) if (byRow(line.row, rowOf(path)) >= 0 && (row === undefined || byRow(line.row, row) < 0)) row = line.row;\n let best = -1;\n lines.forEach((line, k) => {\n if (line.row === row && (best < 0 || Math.abs(k - near) < Math.abs(best - near))) best = k;\n });\n return best;\n}\n\n/**\n * The event a tap or a seek to `path` (`part.row.note`, or `part.row` for the\n * line's start) should start from: the first event at or after that note in\n * its own line, else the line's last one — a closing bar belongs to its line,\n * not the next — else the next line's first. A line sung more than once\n * resolves to the pass nearest event `near` (default: the first pass). A note\n * reached by a মীড় glide has no attack of its own, so the glide's source is\n * returned instead. -1 when nothing sounds from there on.\n */\nexport function eventAt(events: PlayEvent[], path: string, near = -1): number {\n const lines = scheduleLines({ events, totalBeats: 0 });\n const k = lineFor(lines, path, near < 0 ? -1 : lineAt(lines, near));\n if (k < 0) return -1;\n const end = lines[k + 1]?.first ?? events.length;\n let i = lines[k]!.first;\n if (lines[k]!.row === rowOf(path)) while (i < end - 1 && noteOf(events[i]!.path) < noteOf(path)) i++;\n while (i > 0 && events[i]!.glide === true) i--;\n return i;\n}\n\n/** A সম beat-tick: a beat-label digit carrying the reph tick (`1f`/`2F`…). It\n * marks the sam wherever it lands; the digit is a within-line vibhag number, so\n * only the trailing f/F (not the value) identifies sam. Labels live on a note's\n * `above` annotations (see the converter's beat-label handling). */\nconst SAM_TICK = /^\\d+[fF]$/;\n\n/**\n * Where the first সম falls in a song that marks none but opens on loose notes\n * (a pickup): `[part, row, note]`. Swarabitan closes each cycle with `I`\n * (\"তালের এক ফেরা হইয়া গেলে … I\"), opens a section with `II`, and sings what\n * stands before the asthayi's `II` once; NLTR sets each line as whole cycles,\n * with the pickup right-aligned before them. So the first line that opens on\n * a bar starts on sam — else (a creator line never opens on one) the first\n * `I` closes the pickup. Over the 116 loose-note songs that do mark sam, this\n * finds it in 112; the rest are source slips. Undefined for a song that opens\n * on a bar: one that starts mid-cycle there is 7 in 948, all matra slips.\n */\nfunction loosePickupSam(doc: Swaralipi): [number, number, number] | undefined {\n const rows = doc.parts.flatMap((part, p) => part.rows.map((row, r) => ({ p, r, notes: row.notes })));\n const opener = (notes: Note[]) => notes.find((n) => n.bar !== undefined || !isSilent(n));\n const first = rows.findIndex((row) => opener(row.notes) !== undefined);\n if (first < 0 || opener(rows[first]!.notes)!.bar !== undefined) return undefined;\n const line = rows.slice(first + 1).find((row) => opener(row.notes)?.bar !== undefined);\n if (line !== undefined) return [line.p, line.r, 0];\n for (const { p, r, notes } of rows) {\n const i = notes.findIndex((n) => n.bar === 'single');\n if (i >= 0) return [p, r, i];\n }\n return undefined;\n}\n\n/**\n * Walk a document into a flat, time-ordered list of play events.\n *\n * - svara note → an attack at the cursor; advances by `durationMatra ?? 1`.\n * - rest → a silent column that still advances the cursor.\n * - sustain **with** svara (melisma) → a fresh attack (the pitch moves under\n * a held vowel); advances.\n * - sustain **without** svara (আ-কার hold) → no attack, but the previous\n * audible note's ring is extended; still emitted (midi null) so the lyric\n * column highlights; advances.\n * - a svara under a মীড় arc (but not the note the arc opened on) → still its\n * own event, flagged `glide`: the pitch is reached by sliding from the\n * previous attack rather than by striking again (see meendContinuations).\n * - bar / bracket-only / carrier / structural raw → ignored (no event, no\n * advance); an *undecoded* notation cell (see isSilent) instead plays as a\n * rest, so it keeps its matra and the তাল stays aligned.\n *\n * Written order by default; with `repeats` the walk follows the sung order\n * (playOrder), so a column sung twice is two events with one path.\n */\nexport function buildSchedule(doc: Swaralipi, opts: ScheduleOptions = {}): Schedule {\n const tonicPc = parseTonic(opts.tonic ?? doc.meta.tonic);\n const baseOctave = opts.baseOctave ?? 4;\n const events: PlayEvent[] = [];\n let cursor = 0;\n /** Index in `events` of the last pitched attack, for hold-extension. */\n let lastPitched = -1;\n\n // লয় and তাল: a row's mark holds until another row changes it, in written\n // order — so a repeat or a return to the asthayi sings each row at its own\n // tempo and taal, not at whatever the jump came from. `scale` < 1 stretches\n // the written matra over more schedule beats, which is what makes the\n // passage sound slower at one transport tempo.\n const speeds = resolveLaySpeeds(doc.meta.laySpeeds, opts.laySpeeds);\n const withLay = opts.lay !== false;\n const tempo: TempoSegment[] = [{ beat: 0, endBeat: 0, scale: 1, lay: 'drut', taal: doc.meta.taal }];\n const rows = new Map<string, { scale: number; lay: Lay; taal: Taal | null | undefined; glides: Set<number> }>();\n let scale = 1;\n let layNow: Lay = 'drut';\n let taal: Taal | null | undefined = doc.meta.taal;\n doc.parts.forEach((part, p) =>\n part.rows.forEach((row, r) => {\n const lay = withLay ? rowLay(row) : undefined;\n if (lay !== undefined && speeds[lay] !== scale) {\n scale = speeds[lay];\n layNow = lay;\n }\n if (row.taal !== undefined) taal = row.taal;\n rows.set(`${p}.${r}`, { scale, lay: layNow, taal, glides: meendContinuations(row.notes) });\n }),\n );\n\n const order =\n opts.repeats === true\n ? playOrder(doc)\n : doc.parts.flatMap((part, p) => part.rows.flatMap((row, r) => row.notes.map((note, i) => ({ p, r, i, note }))));\n // Each visit's matra from the song's start, and the first সম's (a SAM_TICK,\n // else loosePickupSam's first visit) — *written* matra, so the anacrusis\n // maths stays independent of the লয়, and an excerpt keeps every note on the\n // beat it has in the song.\n const at = [0];\n const loose = loosePickupSam(doc);\n let tick: number | undefined;\n let inferred: number | undefined;\n for (const { p, r, i, note } of order) {\n const m = at[at.length - 1]!;\n if (tick === undefined && note.above?.some((a) => a.raw !== undefined && SAM_TICK.test(a.raw))) tick = m;\n if (inferred === undefined && loose !== undefined && p === loose[0] && r === loose[1] && i >= loose[2]) inferred = m;\n at.push(note.bar === undefined && !isSilent(note) ? m + (note.durationMatra ?? 1) : m);\n }\n const samMatra = tick ?? inferred;\n const { visits, matra } = opts.excerpt\n ? excerptVisits(order, at, opts.excerpt, (v) => rows.get(`${v.p}.${v.r}`)!.taal?.numBeats)\n : { visits: order, matra: 0 };\n let rowNow = '';\n for (const { p, r, i, note } of visits) {\n const row = rows.get(`${p}.${r}`)!;\n if (rowNow !== `${p}.${r}`) {\n rowNow = `${p}.${r}`;\n // The two marks are independent, so a segment starts wherever either moves.\n const last = tempo[tempo.length - 1]!;\n if (row.scale !== last.scale || !sameTaal(row.taal, last.taal)) {\n const seg: TempoSegment = { beat: cursor, endBeat: cursor, scale: row.scale, lay: row.lay, taal: row.taal };\n // Two marks with nothing between them are one switch, not a 0-beat segment.\n if (last.beat === cursor) tempo[tempo.length - 1] = seg;\n else {\n last.endBeat = cursor;\n tempo.push(seg);\n }\n }\n }\n if (note.bar !== undefined || isSilent(note)) continue;\n const path = `${p}.${r}.${i}`;\n const written = note.durationMatra ?? 1;\n const dur = written / row.scale;\n // Any column that takes time can carry graces, a hold or rest included.\n const kan = graceMidis(note.kan, tonicPc, baseOctave);\n const resh = graceMidis(note.resh, tonicPc, baseOctave);\n\n if (note.svara !== undefined) {\n // svara note or melisma — a real attack, unless a মীড় glides into it.\n events.push({\n beat: cursor,\n durationBeats: dur,\n midi: svaraToMidi(note, tonicPc, baseOctave),\n kan,\n resh,\n path,\n kind: note.sustain === true ? 'sustain' : 'note',\n ...(row.glides.has(i) && lastPitched >= 0 ? { glide: true as const } : {}),\n });\n lastPitched = events.length - 1;\n } else if (note.sustain === true) {\n // আ-কার hold — extend the ringing note, emit a silent highlight column.\n if (lastPitched >= 0) events[lastPitched]!.durationBeats += dur;\n events.push({ beat: cursor, durationBeats: dur, midi: null, kan, resh, path, kind: 'sustain' });\n } else {\n // rest.\n events.push({ beat: cursor, durationBeats: dur, midi: null, kan, resh, path, kind: 'rest' });\n }\n cursor += dur;\n }\n\n // Anacrusis: if the first note is at matra M and sam at S in an N-beat\n // cycle, the first note falls (M − S) mod N into the cycle — the count-in a\n // leading rhythm plays — and the next sam is N less that after it (0 when the\n // song starts on sam). No সম at all: the first note is sam. The opening\n // taal's cycle, since that is the one the pickup is sung in. Snapped, since\n // 1/3 and 1/5 matra never sum to an exact integer.\n const numBeats = tempo[0]!.taal?.numBeats;\n let pickupMatra = 0;\n if (numBeats !== undefined && numBeats > 0) {\n pickupMatra = (((matra - (samMatra ?? 0)) % numBeats) + numBeats) % numBeats;\n if (pickupMatra < 1e-6 || pickupMatra > numBeats - 1e-6) pickupMatra = 0;\n }\n tempo[tempo.length - 1]!.endBeat = cursor;\n\n // Both are played at the tempo the song *starts* in.\n const opening = tempo[0]!.scale;\n return {\n events,\n totalBeats: cursor,\n pickupBeats: pickupMatra / opening,\n samBeat: pickupMatra > 0 ? (numBeats! - pickupMatra) / opening : 0,\n tempo,\n };\n}\n","/**\n * Tone.js instrument/asset factories. Tone is **injected** (never imported\n * here) so this module — like the scheduler — stays free of a static `tone`\n * dependency; the player passes the dynamically-imported module in.\n *\n * Melodic instruments are a small registry (INSTRUMENTS) of Tone.Sampler\n * note→file maps + where to fetch them. `piano` (CC-BY Salamander) is the\n * default and CDN-hosted, as are `harmonium`/`violin`/`flute` (CC-BY,\n * tonejs-instruments); `santoor` is local (under the player's `soundsBaseUrl`).\n * Consumers can register more (e.g. a self-hosted sitar) via the player's\n * `customInstruments` option — true sampled sitar/sarod/sarangi/esraj have no\n * free web set, only commercial Kontakt libraries.\n *\n * Asset layout under `soundsBaseUrl`:\n * santoor/<note>.mp3 c4..c7 + sharps (37 files)\n * tanpura/<pc>.mp3 12 pitch classes (c, cs, d, …)\n * tabla/<seg>/<seg><bpm>bpm.mp3 seg = <taal>[-<variation>], bpm 60..300 step 15\n * metronome/metro2.mp3\n */\n// Import TAALS from the taals subpath (not the ../spec/index barrel): the\n// barrel re-exports schema.ts, which statically imports zod — pulling that into\n// the player would break its \"loads bare in a browser\" guarantee. taals.ts has\n// only a type-only schema import, so this keeps the player runtime zod-free.\nimport type { Taal } from '../spec/schema.js';\nimport { TAALS, type TaalId } from '../spec/taals.js';\nimport { sCurve, sampleFileName } from './pitch.js';\n\n/** The dynamically-imported Tone module, typed without importing it. */\nexport type ToneModule = typeof import('tone');\n\n/** A melodic instrument: a Tone.Sampler note→filename map + where to find it. */\nexport interface InstrumentDef {\n /** Human label for UIs. */\n label: string;\n /** Tone.Sampler `urls`: note name (`C#4`) → filename (`Cs4.mp3`). */\n urls: Record<string, string>;\n /** Sample directory: an absolute URL, or — when `local` — a path segment\n * appended to the player's `soundsBaseUrl`. */\n baseUrl: string;\n /** `baseUrl` is relative to `soundsBaseUrl` (needs it set). */\n local?: boolean;\n /** Sampler release time in seconds. */\n release?: number;\n}\n\n/** Built-in melody instrument ids (consumers may add their own via the\n * player's `customInstruments`, so the runtime id type stays open). */\nexport type InstrumentId = string;\n\n/**\n * Default host for the project's samples (santoor / tabla / tanpura /\n * metronome) — CORS-enabled, so the player works with zero config. Override via\n * the player's `soundsBaseUrl` to self-host. (Melody defaults to the CDN-hosted\n * piano, so it needs no host.) Licences: see THIRD-PARTY.md.\n */\nexport const DEFAULT_SOUNDS_BASE = 'https://bitoron.pages.dev/audio/instruments/';\n/** CC-BY Salamander Grand Piano (Tone's de-facto piano), CDN-hosted. */\nexport const SALAMANDER_BASE = 'https://tonejs.github.io/audio/salamander/';\n/** CC-BY tonejs-instruments sample CDN (harmonium/violin/flute). */\nexport const TONEJS_INSTRUMENTS_BASE = 'https://nbrosowsky.github.io/tonejs-instruments/samples/';\n\n/** Build a Tone.Sampler `urls` map from bare note keys (`C#4` → `Cs4.mp3`). */\nfunction keyMap(keys: readonly string[]): Record<string, string> {\n const m: Record<string, string> = {};\n for (const k of keys) m[k] = `${k.replace('#', 's')}.mp3`;\n return m;\n}\n\nconst PIANO_KEYS = [\n 'A0', 'C1', 'D#1', 'F#1', 'A1', 'C2', 'D#2', 'F#2', 'A2', 'C3', 'D#3', 'F#3',\n 'A3', 'C4', 'D#4', 'F#4', 'A4', 'C5', 'D#5', 'F#5', 'A5', 'C6', 'D#6', 'F#6',\n 'A6', 'C7', 'D#7', 'F#7', 'A7', 'C8',\n] as const;\n// harmonium — a core Rabindrasangeet accompaniment (C2..C5). The CDN set has no F#4 (404).\nconst HARMONIUM_KEYS = [\n 'C2', 'C#2', 'D2', 'D#2', 'E2', 'F2', 'F#2', 'G2', 'G#2', 'A2', 'A#2',\n 'C3', 'C#3', 'D3', 'D#3', 'E3', 'F3', 'F#3', 'G3', 'G#3', 'A3', 'A#3',\n 'C4', 'C#4', 'D4', 'D#4', 'E4', 'F4', 'G4', 'G#4', 'A4', 'A#4',\n 'C5', 'C#5', 'D5',\n] as const;\nconst VIOLIN_KEYS = ['A3', 'C4', 'E4', 'G4', 'A4', 'C5', 'E5', 'G5', 'A5', 'C6', 'E6', 'G6', 'A6', 'C7'] as const;\nconst FLUTE_KEYS = ['C4', 'E4', 'A4', 'C5', 'E5', 'A5', 'C6', 'E6', 'A6', 'C7'] as const;\n\n/** Built-in melody instruments. santoor is local; the rest are CDN-hosted\n * (CC-BY) so they need only network — `pianoBaseUrl`/`customInstruments`\n * override for self-hosting. */\nexport const INSTRUMENTS: Record<string, InstrumentDef> = {\n piano: { label: 'Grand piano', urls: keyMap(PIANO_KEYS), baseUrl: SALAMANDER_BASE, release: 1 },\n santoor: { label: 'Santoor', urls: santoorUrls(), baseUrl: 'santoor/', local: true, release: 1.2 },\n harmonium: { label: 'Harmonium', urls: keyMap(HARMONIUM_KEYS), baseUrl: `${TONEJS_INSTRUMENTS_BASE}harmonium/`, release: 1.4 },\n violin: { label: 'Violin', urls: keyMap(VIOLIN_KEYS), baseUrl: `${TONEJS_INSTRUMENTS_BASE}violin/`, release: 1 },\n flute: { label: 'Flute', urls: keyMap(FLUTE_KEYS), baseUrl: `${TONEJS_INSTRUMENTS_BASE}flute/`, release: 1 },\n};\n\n/** Taals with recorded tabla loops (everything else → metronome fallback). */\nexport const SAMPLED_TAALS: ReadonlySet<TaalId> = new Set(\n Object.keys(TAALS) as TaalId[],\n);\n\n/** Available tabla loop tempos (file suffix `…<bpm>bpm.mp3`). */\nexport const TABLA_BPMS: readonly number[] = Array.from({ length: 17 }, (_, i) => 60 + i * 15);\n\n/**\n * Tabla loop variations per taal. Most taals have one unnamed loop at\n * `tabla/<id>/`; an entry here overrides that:\n * - `variations` lists the variation suffixes, **first = default**.\n * A lone named variation (shashthi → `pro`, i.e. `tabla/shashthi-pro/`) IS\n * the default; later entries are premium upsells the player never auto-selects.\n * An empty-string entry (kehrwa → `''`) means the unnamed `tabla/<id>/` loop\n * is the default and a named entry follows it as an upsell.\n * - `skipBpms` are grid tempos this taal's loops were not recorded at.\n * Consumers read this to build a variation/upsell UI; the player itself only\n * ever plays the default (or whatever a doc's `meta.taal.variation` pins).\n */\nexport const TABLA_VARIATIONS: Record<\n string,\n { variations: string[]; skipBpms?: number[] }\n> = {\n // ষষ্ঠী loops live under `tabla/shashthi-pro/`; full bpm grid recorded except 225.\n shashthi: { variations: ['pro'], skipBpms: [225] },\n // Kehrwa keeps its unnamed default loop; `qawwali` (tabla/kehrwa-qawwali/) is a\n // premium upsell variation recorded 90–300 (no 60/75).\n // ponytail: skipBpms is per-taal, so it can't restrict qawwali's 60/75 without\n // also dropping them from the default (which has them) — a qawwali doc pinned\n // ≤67 bpm 404s harmlessly. Make skipBpms per-variation only if that edge bites.\n kehrwa: { variations: ['', 'qawwali'] },\n};\n\n/** Tabla tempos actually available for a taal: the grid minus any it lacks. */\nexport function tablaBpms(taalId: string): readonly number[] {\n const skip = TABLA_VARIATIONS[taalId]?.skipBpms;\n return skip && skip.length ? TABLA_BPMS.filter((b) => !skip.includes(b)) : TABLA_BPMS;\n}\n\n/** CDN directory/filename segment for a taal's tabla loop: `<taalId>` or\n * `<taalId>-<variation>` (explicit variation, else the taal's default). */\nfunction tablaSeg(taalId: string, variation?: string): string {\n const v = variation ?? TABLA_VARIATIONS[taalId]?.variations[0]; // default = first variation, else unnamed\n return v ? `${taalId}-${v}` : taalId;\n}\n\n/** Ensure exactly one trailing slash. */\nexport function normalizeBase(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\n/** The 37 santoor samples, as a Tone.Sampler `urls` map (`C4` → `c4.mp3`). */\nexport function santoorUrls(): Record<string, string> {\n const urls: Record<string, string> = {};\n const add = (midi: number) => {\n const stem = sampleFileName(midi); // e.g. cs4\n const name = stem.replace('s', '#').replace(/^(.)/, (c) => c.toUpperCase()); // C#4\n urls[name] = `${stem}.mp3`;\n };\n for (let midi = 60; midi <= 95; midi++) add(midi); // C4..B6 (full)\n add(96); // C7\n return urls;\n}\n\nconst PC_BASE: Record<string, number> = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 };\n\n/** Parse a sample note name (`C#4`, `Ds3`, `Bb2`) to a MIDI number. */\nexport function noteToMidi(name: string): number {\n const m = /^([a-g])([#sb]?)(-?\\d+)$/i.exec(name.trim());\n if (!m) return NaN;\n const base = PC_BASE[m[1]!.toLowerCase()]!;\n const acc = m[2] === 'b' ? -1 : m[2] === '' ? 0 : 1; // # / s → sharp\n return (Number(m[3]) + 1) * 12 + base + acc;\n}\n\n/**\n * Restrict a Sampler `urls` map to just the samples needed to cover MIDI\n * `[lo, hi]`: every sample inside the range, plus the nearest one below and\n * above it (so Tone interpolates the edges without extrapolating). Cuts a\n * typical song from ~37 santoor files to a handful — a big win on mobile and\n * never worse on fast links (Tone fetches what's left in parallel). The\n * Sampler pitch-shifts from the nearest sample, so audio is unchanged.\n */\nexport function subsetUrls(\n urls: Record<string, string>,\n lo: number,\n hi: number,\n): Record<string, string> {\n const entries = Object.entries(urls)\n .map(([k, f]) => ({ k, f, midi: noteToMidi(k) }))\n .filter((e) => Number.isFinite(e.midi))\n .sort((a, b) => a.midi - b.midi);\n if (entries.length === 0) return { ...urls };\n\n const keep = new Set<string>();\n for (const e of entries) if (e.midi >= lo && e.midi <= hi) keep.add(e.k);\n // nearest sample at/below lo and at/above hi for clean interpolation\n let floor: string | undefined;\n let ceil: string | undefined;\n for (const e of entries) if (e.midi <= lo) floor = e.k;\n for (const e of entries) if (e.midi >= hi) { ceil = e.k; break; }\n if (floor) keep.add(floor);\n if (ceil) keep.add(ceil);\n if (keep.size === 0) {\n // range entirely outside the sample set — keep the single nearest sample\n const mid = (lo + hi) / 2;\n const nearest = entries.reduce((a, b) => (Math.abs(b.midi - mid) < Math.abs(a.midi - mid) ? b : a));\n keep.add(nearest.k);\n }\n\n const out: Record<string, string> = {};\n for (const e of entries) if (keep.has(e.k)) out[e.k] = e.f;\n return out;\n}\n\n/** Resolve a representative sample URL for an instrument (its first sample),\n * used to probe availability. undefined when a local instrument has no\n * `soundsBaseUrl` or the def has no samples. */\nexport function instrumentSampleUrl(def: InstrumentDef, soundsBaseUrl?: string): string | undefined {\n if (def.local && soundsBaseUrl === undefined) return undefined;\n const base = def.local ? `${normalizeBase(soundsBaseUrl ?? '')}${def.baseUrl}` : def.baseUrl;\n const file = Object.values(def.urls)[0];\n return file === undefined ? undefined : `${normalizeBase(base)}${file}`;\n}\n\n/**\n * Liveness check for a sample URL: a single tiny ranged GET (one byte), the\n * same CORS-enabled fetch Tone uses to load the buffer — so a pass means Tone\n * can actually load it. Resolves false on any error/timeout/non-2xx, and false\n * (no throw) when `fetch` is unavailable (Node/SSR). `Range: bytes=0-0` is a\n * CORS-safelisted header, so no preflight.\n */\nexport async function probeUrl(url: string, timeoutMs = 6000): Promise<boolean> {\n if (typeof fetch === 'undefined') return false;\n const ctrl = typeof AbortController !== 'undefined' ? new AbortController() : undefined;\n const timer = ctrl ? setTimeout(() => ctrl.abort(), timeoutMs) : undefined;\n try {\n const res = await fetch(url, {\n method: 'GET',\n headers: { Range: 'bytes=0-0' },\n cache: 'no-store',\n signal: ctrl?.signal,\n });\n return res.ok; // 200 / 206\n } catch {\n return false;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\n/**\n * Snap a tabla loop's end to the nearest whole beat of its measured length so a\n * slightly-mistrimmed file still phase-locks to the melody grid instead of\n * drifting a fraction of a beat each cycle. `spb` = seconds per beat (60/bpm).\n * No-op for correctly trimmed loops (already an integer beat count); never\n * extends past the buffer — a too-short file can't be repaired here.\n *\n * ponytail: belt-and-braces for off-spec audio; the real fix is trimming each\n * loop to exactly `cycles × numBeats × 60/bpm` seconds at production time.\n */\nexport function quantizeLoopEnd(durationSec: number, spb: number): number {\n if (spb <= 0) return durationSec;\n const beats = Math.round(durationSec / spb);\n if (beats < 1) return durationSec; // too short to snap to a beat\n return Math.min(beats * spb, durationSec);\n}\n\n/** Snap an arbitrary bpm to the nearest available tabla tempo (default grid;\n * pass a taal's `tablaBpms()` so it never snaps to a tempo that taal lacks). */\nexport function nearestTablaBpm(bpm: number, bpms: readonly number[] = TABLA_BPMS): number {\n return bpms.reduce((best, b) => (Math.abs(b - bpm) < Math.abs(best - bpm) ? b : best), bpms[0]!);\n}\n\n/** URL of the tabla loop for a taal at a (snapped) bpm, optionally a named\n * variation (defaults to the taal's default variation — see TABLA_VARIATIONS). */\nexport function tablaUrl(base: string, taalId: string, bpm: number, variation?: string): string {\n const seg = tablaSeg(taalId, variation);\n return `${normalizeBase(base)}tabla/${seg}/${seg}${bpm}bpm.mp3`;\n}\n\n/**\n * Pitch class (0 = C) the tabla loops were recorded at: their dayan (the tuned\n * right drum) rings at Sa ≈ C — measured off the CDN loops themselves\n * (spectral peak of the stroke decays, ~529 Hz = C5 +20 cents, consistent\n * across taals and across every bpm variant, i.e. the tempo set was\n * time-stretched, not resampled). Calibration knob: re-measure and change this\n * if the loop set is ever re-recorded.\n */\nexport const TABLA_TONIC_SEMITONE = 0;\n\n/**\n * Semitones to pitch-shift a tabla loop so its dayan matches the song's Sa.\n * Wrapped to the nearer direction (−5…+6): the drum is octave-agnostic, so a\n * B tonic shifts down 1 rather than up 11.\n */\nexport function tablaShiftSemitones(tonicSemitone: number): number {\n const d = (((tonicSemitone - TABLA_TONIC_SEMITONE) % 12) + 12) % 12;\n return d > 6 ? d - 12 : d;\n}\n\n/**\n * Grain settings for a retuned tabla loop (`Tone.GrainPlayer`, which detunes\n * independently of playback rate — so the loop keeps its recorded tempo and\n * stays phase-locked).\n *\n * Why not `Tone.PitchShift` after a plain `Player`: measured offline on the\n * teentaal loop, both shift accurately (±2 and −5 semitones confirmed by\n * spectral cross-correlation), but PitchShift's delay lines push the first\n * stroke 20–35 ms late (audibly behind the melody) and smear the spectrum;\n * GrainPlayer holds the onset at ~4 ms. Grains short enough not to blur the\n * strokes, overlapped half-way so the loop stays seamless.\n */\nexport const TABLA_GRAIN_SEC = 0.06;\nexport const TABLA_GRAIN_OVERLAP_SEC = 0.03;\n\n/** URL of the metronome click. */\nexport function metronomeUrl(base: string): string {\n return `${normalizeBase(base)}metronome/metro2.mp3`;\n}\n\n/** Build the metronome click `Tone.Player`. */\nexport function createMetronome(Tone: ToneModule, base: string) {\n return new Tone.Player(metronomeUrl(base));\n}\n\n/** Tanpura pitch-class sample stems (filename = `<stem>.mp3`). */\nexport const TANPURA_PCS = ['c', 'cs', 'd', 'ds', 'e', 'f', 'fs', 'g', 'gs', 'a', 'as', 'b'] as const;\n\n/* ---- Drum kit (Western-drumset rendering of an Indian taal) ------------\n *\n * A real drumset \"translation\" of tabla bols is an established practice\n * (e.g. Sunny Jain's Drum Atlas: India — kick on sam, snare on the accented\n * tali claps, hi-hat filling/ghosting the khaali wave), not something\n * invented here. DRUM_VOICES are one-shot acoustic-kit samples (CC0-cleared\n * Apache-2.0 Tonejs/audio collection, https://github.com/Tonejs/audio,\n * already the CDN this project uses directly for the Salamander piano) —\n * same trust tier as the other CDN-hosted instruments, no new hosting.\n */\nexport const DRUM_KIT_BASE = 'https://tonejs.github.io/audio/drum-samples/acoustic-kit/';\n\nexport type DrumVoice = 'kick' | 'snare' | 'hihat' | 'tom1' | 'tom2' | 'tom3';\nconst DRUM_FILES: Record<DrumVoice, string> = {\n kick: 'kick.mp3',\n snare: 'snare.mp3',\n hihat: 'hihat.mp3',\n tom1: 'tom1.mp3',\n tom2: 'tom2.mp3',\n tom3: 'tom3.mp3',\n};\n\n/** Build the drum-kit `Tone.Players` (one-shot voices, not looped/pitched). */\nexport function createDrumKit(Tone: ToneModule, base: string = DRUM_KIT_BASE) {\n const urls: Record<string, string> = {};\n for (const [voice, file] of Object.entries(DRUM_FILES)) urls[voice] = file;\n return new Tone.Players({ urls, baseUrl: normalizeBase(base) });\n}\n\n/**\n * Per-beat drumset voice for one তাল cycle, following sam/tali/khaali theory:\n * sam (cycle start) → kick, the first beat of each accented (non-khaali)\n * vibhag → snare (the tali clap), the first beat of a khaali vibhag → closed\n * hihat (the khaali \"wave off\"), every other beat → hihat (fill, keeping the\n * kit's groove going the way a tabla's filler strokes do).\n */\nexport function drumPattern(taal: Pick<Taal, 'numBeats' | 'sam' | 'bhaags' | 'khaali'>): DrumVoice[] {\n const n = taal.numBeats;\n const sam = taal.sam ?? 0;\n const khaali = new Set(taal.khaali ?? []);\n const bhaags = taal.bhaags ?? [n];\n const pattern: DrumVoice[] = new Array(n).fill('hihat');\n\n let pos = 0;\n for (const len of bhaags) {\n pattern[pos] = khaali.has(pos) ? 'hihat' : 'snare';\n pos += len;\n }\n pattern[sam] = 'kick';\n return pattern;\n}\n\n/**\n * Build a melody `Tone.Sampler` for an instrument def. Resolves the sample\n * directory (local → under `soundsBaseUrl`, else the def's absolute CDN URL)\n * and, when a MIDI `range` is given, loads only the samples that cover it.\n */\nexport function createSampler(\n Tone: ToneModule,\n def: InstrumentDef,\n soundsBaseUrl: string | undefined,\n range?: { lo: number; hi: number },\n) {\n const base = def.local ? `${normalizeBase(soundsBaseUrl ?? '')}${def.baseUrl}` : def.baseUrl;\n const urls = range ? subsetUrls(def.urls, range.lo, range.hi) : def.urls;\n return new Tone.Sampler({ urls, baseUrl: normalizeBase(base), release: def.release ?? 1 });\n}\n\n/* ---- মীড় (meend) — the sounded glide -------------------------------------\n *\n * A মীড় is one continuous sound whose pitch travels between svaras; the notes\n * it covers are never re-struck. A `Tone.Sampler` cannot do that — it has no\n * pitch parameter at all (checked against tone 15's own typings). What it does\n * have, one layer down, is `ToneBufferSource.playbackRate`, a real AudioParam:\n * so a glide is the instrument's own sample, started once, with its playback\n * rate automated — a tape slide, which is exactly what a hardware sampler does\n * for portamento.\n *\n * The pitch is automated as an S-curve (see `sCurve`), not a straight line, and\n * it leaves the source svara only after `MEEND_HOLD` of the gap so the written\n * note keeps its identity before rolling into the next — arriving exactly on\n * the target's own matra.\n *\n * ponytail: the glide reads from a second `ToneAudioBuffers` over the same\n * URLs as the Sampler (the browser HTTP cache means no extra download, just a\n * second decode). Share one buffer set if memory ever matters.\n */\n\n/**\n * Fraction of the gap between two মীড় notes spent holding the source pitch\n * before the slide begins. 0 = slide the whole way (an alaap-slow meend);\n * 0.5 = hold half the note, then roll into the target.\n */\nexport const MEEND_HOLD = 0.5;\n\n/** Automation points per glide leg — enough to hear as continuous. */\nconst GLIDE_STEPS = 24;\n\n/** Sampler `urls` key whose pitch is nearest `midi` (the sample to slide). */\nexport function nearestSampleKey(urls: Record<string, string>, midi: number): string {\n let best = '';\n let bestDiff = Infinity;\n for (const key of Object.keys(urls)) {\n const diff = Math.abs(noteToMidi(key) - midi);\n if (diff < bestDiff) {\n bestDiff = diff;\n best = key;\n }\n }\n return best;\n}\n\n/** The same samples `createSampler` loads, as raw buffers for the glide voice. */\nexport function createBuffers(\n Tone: ToneModule,\n def: InstrumentDef,\n soundsBaseUrl: string | undefined,\n range?: { lo: number; hi: number },\n) {\n const base = def.local ? `${normalizeBase(soundsBaseUrl ?? '')}${def.baseUrl}` : def.baseUrl;\n const urls = range ? subsetUrls(def.urls, range.lo, range.hi) : def.urls;\n return { buffers: new Tone.ToneAudioBuffers({ urls, baseUrl: normalizeBase(base) }), urls };\n}\n\n/** One মীড় leg: the pitch to reach and the absolute time to reach it by. */\nexport interface GlideLeg {\n midi: number;\n /** Seconds on the transport; `legs[0]` is the attack itself. */\n at: number;\n}\n\n/**\n * Sound one মীড় phrase: a single attack on `legs[0]` whose pitch then slides\n * through every following leg, ending at `endSec`. Used by both the live\n * player and the offline export.\n */\nexport function triggerGlide(\n Tone: ToneModule,\n buffers: InstanceType<ToneModule['ToneAudioBuffers']>,\n urls: Record<string, string>,\n dest: InstanceType<ToneModule['Gain']>,\n legs: readonly GlideLeg[],\n endSec: number,\n release = 1,\n hold = MEEND_HOLD,\n): void {\n const key = nearestSampleKey(urls, legs[0]!.midi);\n if (key === '' || !buffers.has(key)) return;\n const sampleMidi = noteToMidi(key);\n const rate = (midi: number) => Math.pow(2, (midi - sampleMidi) / 12);\n\n const source = new Tone.ToneBufferSource({\n url: buffers.get(key),\n fadeOut: release,\n curve: 'exponential',\n // Bind to the destination's context explicitly. `Tone.Offline` restores the\n // global context the moment it starts rendering, so a node built inside a\n // transport callback would otherwise land on the *online* context and the\n // offline export would render the glide as silence.\n context: dest.context,\n }).connect(dest);\n // Clean up after the note — but only on a live context. An offline render\n // runs its whole clock *before* `startRendering()`, so an onended-dispose\n // would disconnect the node before a single sample was rendered (the export\n // came out silent). The offline context is discarded wholesale anyway.\n if (!dest.context.isOffline) source.onended = () => source.dispose();\n\n const rates = source.playbackRate;\n rates.setValueAtTime(rate(legs[0]!.midi), legs[0]!.at);\n for (let k = 1; k < legs.length; k++) {\n const from = legs[k - 1]!;\n const to = legs[k]!;\n const start = from.at + (to.at - from.at) * hold;\n const values: number[] = [];\n for (let n = 0; n <= GLIDE_STEPS; n++) {\n values.push(rate(from.midi + (to.midi - from.midi) * sCurve(n / GLIDE_STEPS)));\n }\n rates.setValueCurveAtTime(values, start, Math.max(to.at - start, 0.02));\n }\n source.start(legs[0]!.at, 0, Math.max(endSec - legs[0]!.at, 0.05));\n}\n\n/** Build a tanpura `Tone.Players` loading only the given pitch-class stems\n * (the drone only ever plays Sa + Pa, so we fetch 2 files, not 12). */\nexport function createTanpura(Tone: ToneModule, base: string, stems: readonly string[] = TANPURA_PCS) {\n const urls: Record<string, string> = {};\n for (const s of stems) urls[s] = `${s}.mp3`;\n return new Tone.Players({ urls, baseUrl: `${normalizeBase(base)}tanpura/` });\n}\n","/**\n * `SwaralipiPlayer` — the stateful audio facade over Tone.js.\n *\n * Tone is **dynamically imported** on first `play()` so that importing\n * `@ugfoundation/swaralipi-js/player` in Node/SSR (or just to reach the pure\n * helpers) never pulls in the audio engine or touches `AudioContext`. The\n * pure cores (pitch.ts, schedule.ts, instruments.ts) carry the logic; this\n * class only wires them onto the Tone Transport and drives the viewer's\n * `highlight()`.\n *\n * Model: build a beat-timed `Schedule`, lay each note onto the Transport in\n * seconds (`beat × 60/bpm`), loop a tabla (or click a metronome) underneath,\n * drone a tanpura, and fire highlights on Tone's draw thread. Practice rides\n * the same Transport: a seek moves its position, a repeated line is its loop,\n * and the notes are persistent events so each pass plays them again. A\n * setting change while playing re-arranges from the current note (no\n * mid-stream tempo ramp).\n */\nimport type { Gain, GrainPlayer, Players, Player, Sampler, ToneAudioBuffers, Unit } from 'tone';\nimport type { Swaralipi } from '../spec/index.js';\n// Taal type-only from schema.ts (not the barrel) — keeps the player zod-free,\n// same reason instruments.ts imports TAALS from the taals subpath.\nimport type { Taal } from '../spec/schema.js';\n// TAALS from the taals subpath, not the barrel — see the note in instruments.ts\n// (the barrel pulls zod, which would defeat the player's bare-load guarantee).\nimport { TAALS, type TaalId } from '../spec/taals.js';\nimport type { LaySpeeds } from '../spec/lay.js';\nimport type { Excerpt } from './lyrics.js';\nimport { midiToSampleName, parseTonic } from './pitch.js';\nimport {\n GRACE_STEP,\n buildSchedule,\n byRow,\n eventAt,\n glideTargets,\n graceTouches,\n lineAt,\n lineFor,\n scheduleLines,\n type Line,\n type Schedule,\n type TempoSegment,\n} from './schedule.js';\nimport {\n DEFAULT_SOUNDS_BASE,\n INSTRUMENTS,\n SAMPLED_TAALS,\n TABLA_GRAIN_OVERLAP_SEC,\n TABLA_GRAIN_SEC,\n TANPURA_PCS,\n createDrumKit,\n createBuffers,\n createMetronome,\n createSampler,\n createTanpura,\n drumPattern,\n instrumentSampleUrl,\n nearestTablaBpm,\n normalizeBase,\n probeUrl,\n quantizeLoopEnd,\n tablaBpms,\n triggerGlide,\n tablaShiftSemitones,\n tablaUrl,\n type InstrumentDef,\n type InstrumentId,\n type ToneModule,\n} from './instruments.js';\n\n/** Seconds the accompaniment fades over when playback is stopped. */\nconst STOP_FADE_SEC = 0.5;\n\n/**\n * How long the outgoing tabla loop rings on under the incoming one at a লয়\n * or তাল change. The new loop starts clean on the boundary (which is a সম), so\n * this only lets the previous stroke decay instead of being cut mid-skin — the\n * transition a tabla player actually makes when the laya or taal turns over.\n */\nconst LAY_TAIL_SEC = 0.12;\n\n/**\n * How far before its target a start or a seek puts the transport. Tone 15.5\n * skips the tick a clock *starts* on whenever float error lands it a hair\n * early (its \"advance past ticks before this window\" guard), and whatever sat\n * on that tick was lost: measured, 2 in 25 fresh plays dropped their first\n * note and never started the tabla (whose synced start is also a tick-0\n * event). Starting a couple of ticks early leaves that tick empty. At least\n * two ticks at 40 bpm, and far under the 0.1 s a tap can take to feel instant.\n */\nconst START_PREROLL_SEC = 0.02;\n\n/** Taal mode has no document and so no লয়: one open-ended segment at the\n * requested tempo. */\nconst TAAL_MODE_TEMPO: readonly TempoSegment[] = [\n { beat: 0, endBeat: Infinity, scale: 1, lay: 'drut' },\n];\n\n/**\n * How far ahead of its note `onEvent` is fired, on top of the transport's own\n * lookahead. It exists for one consumer: OS media-session metadata (a lock\n * screen's lyric line), where the write still has to cross into the system's\n * Now Playing store and wait for that surface to repaint — iOS refreshes an\n * Always-On display only about once a second, by design (Apple DTS,\n * developer.apple.com/forums/thread/812421) — so a write that lands after the\n * note is not seen until the next refresh. Leading it cannot make the line\n * late, only early, and an early lock-screen line reads as a cue. Capped at one\n * matra at the call site so a fast tempo can't run a whole beat ahead.\n *\n * ponytail: no web API can measure the OS's own latency, so this is a\n * calibration knob, not a measurement — retune it against a device.\n */\nconst MEDIA_LEAD_SEC = 0.25;\n\nexport type PlayerState = 'idle' | 'loading' | 'ready' | 'playing' | 'paused';\nexport type RhythmMode = 'tabla' | 'drums' | 'metronome' | 'none';\n\n/** Repeated lines, as `part.row` paths (the viewer's `data-row`), inclusive. */\nexport interface LineRange {\n from: string;\n to: string;\n}\n\n/** What the practice controls show: the repeated lines, whether the learner\n * sings each pass back, and whether the pass now sounding is theirs. */\nexport interface PracticeState {\n loop: LineRange | null;\n echo: boolean;\n yourTurn: boolean;\n}\n\nexport interface PlayerOptions {\n /** Base URL for the project's samples (santoor/tabla/tanpura/metronome).\n * Defaults to `DEFAULT_SOUNDS_BASE` (the project's CORS-enabled CDN), so the\n * player works with zero config; override to self-host. */\n soundsBaseUrl?: string;\n /** Grand-piano sample host. Default: the Salamander CDN (see SALAMANDER_BASE).\n * Set this to self-host the piano under your own URL. */\n pianoBaseUrl?: string;\n /** Tonic (Sa). Accepts `C`, `C#`, `cs`… Default: doc tonic, else `C`. */\n tonic?: string;\n /** Tempo in matra/min — the **দ্রুত** (fast) tempo; লয় marks scale down from\n * it. Default 90. Snapped to the 15-grid while tabla plays. */\n bpm?: number;\n /** Override the লয় tempo factors, e.g. `{ vilambit: 0.6 }`. Defaults come\n * from the document's `meta.laySpeeds`, else `LAY_SPEEDS` (drut 1, madhya\n * 0.75, vilambit 0.5). */\n laySpeeds?: LaySpeeds;\n /** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */\n baseOctave?: number;\n /** Active melody instrument id (a built-in or a `customInstruments` key).\n * Default `piano` (CDN-hosted, zero-config). Built-ins: piano, santoor,\n * harmonium, violin, flute. */\n instrument?: InstrumentId;\n /** Instrument ids the UI may expose. Default: all built-ins. Narrow it to\n * e.g. `['santoor','harmonium']` to limit the picker. */\n instruments?: InstrumentId[];\n /** Extra melody instruments, keyed by id — e.g. a self-hosted sitar/sarod.\n * (True sampled sitar/sarod/sarangi/esraj have no free web set; supply your\n * own Tone.Sampler `urls` + `baseUrl` here and they slot into the picker.) */\n customInstruments?: Record<string, InstrumentDef>;\n /** Rhythm accompaniment. Default `tabla` (→ metronome for unsampled taals).\n * `drums` sequences a Western drumset (kick/snare/hihat) to the taal's\n * sam/tali/khaali structure — a genuine \"drum atlas\"-style translation,\n * not a loop; works for every taal (no per-taal sample requirement). */\n rhythm?: RhythmMode;\n /** Rhythm first, for a song that opens on a pickup (অনাগত): the tabla /\n * drums / metronome play the rest of that cycle and the melody comes in on\n * its own beat — অতীত-গ্রহ, the tāla before the song. Default false: the\n * melody starts at once and the rhythm comes in on the সম — অনাগত-গ্রহ,\n * the song before the tāla (Kohala's Tālalakṣaṇa). The tanpura sounds from\n * the start either way, and a song that opens on sam plays the same. */\n countIn?: boolean;\n /** Play the tanpura drone. Default true. */\n tanpura?: boolean;\n /** Sing the song's form: each `{ }` twice, `( )` only the first time, the\n * `[ ]` notes on the repeat, and back to the asthayi at each kali's end\n * (when a ‖ says where to stop). Default true; false plays it as written. */\n repeats?: boolean;\n /** Stop playback after this many seconds (a policy-neutral preview cap).\n * Default `Infinity` (unlimited). The library only enforces the number it is\n * handed; who is capped / the value / the upsell is the consumer's policy. */\n previewLimitSec?: number;\n /** Called when the preview cap stops playback (so the consumer can show an\n * upsell). Not called on a normal stop()/end. */\n onLimit?: () => void;\n /** Called with the active note's `part.row.note` path, or null when idle.\n * `yourTurn` is true while the melody is silent for the learner to sing\n * (see `setEcho`): the note is where they should be, not what is sounding. */\n onHighlight?: (path: string | null, yourTurn?: boolean) => void;\n /** Called whenever the repeat, the sing-back or the learner's turn changes. */\n onLoop?: (state: PracticeState) => void;\n /** The same path, but fired on the AUDIO clock — Tone's worker ticker, the one\n * that fires the notes themselves — so it keeps arriving while the page is\n * hidden. `onHighlight` cannot: it runs on Tone.Draw, i.e.\n * `requestAnimationFrame`, which stops the moment a screen locks, so anything\n * hanging off it freezes until the reader looks at the page again. Use this for\n * consumers that are not drawing (media-session metadata, analytics); it fires\n * early — one transport lookahead (~0.1s) plus MEDIA_LEAD_SEC — and only in\n * doc mode. */\n onEvent?: (path: string | null) => void;\n /** Taal mode only (`loadTaal`): called on the draw thread once per matra with\n * the beat index within the cycle (0-based, `< numBeats`), so a consumer can\n * highlight the active theka bol / drum-staff note. Never fired in doc mode. */\n onBeat?: (beatInCycle: number) => void;\n /** Called on every state transition. */\n onState?: (state: PlayerState) => void;\n}\n\n/** Minimal shape of the viewer element the player drives (avoids a hard\n * dependency on the viewer module). `highlight` returns the highlighted node\n * (or null) so bindSheet can optionally scroll it into view. */\ninterface HighlightTarget {\n highlight(path: string, yourTurn?: boolean): HTMLElement | null;\n clearHighlights(): void;\n /** Shade the repeated lines, and mark the learner's turn on them. */\n markLoop?(loop: LineRange | null, yourTurn: boolean): void;\n}\n\n/** The `<swaralipi-sheet>` tap event: play from `path`, or with Shift,\n * stretch the repeat to its line. */\ntype SeekEvent = CustomEvent<{ path: string; extend: boolean }>;\n\n/**\n * A GrainPlayer that survives a seek. When the transport jumps (a tap-to-play,\n * a repeat wrapping), Tone restarts a synced source with its offset in\n * transport seconds — but a loop stretched to `playbackRate` has only played\n * rate × that much of its buffer, so a stretched tabla came back out of phase\n * (Tone.js issue #349, still open in 15.1).\n */\nconst seekableGrain = (Tone: ToneModule) =>\n class extends Tone.GrainPlayer {\n protected override _start(time?: Unit.Time, offset?: Unit.Time, duration?: Unit.Time): void {\n super._start(time, offset === undefined ? offset : this.toSeconds(offset) * this.playbackRate, duration);\n }\n };\n\n/** MIDI span (incl. কণ/রেশ graces) of a schedule's notes, for sample subsetting;\n * undefined when there are no pitched events. */\nfunction midiRange(schedule: Schedule): { lo: number; hi: number } | undefined {\n let lo = Infinity;\n let hi = -Infinity;\n for (const ev of schedule.events) {\n for (const m of [ev.midi, ...ev.kan, ...ev.resh]) {\n if (m !== null) {\n if (m < lo) lo = m;\n if (m > hi) hi = m;\n }\n }\n }\n return lo <= hi ? { lo, hi } : undefined;\n}\n\n/**\n * Seconds the melody is pushed later: the count-in, only when a rhythm leads\n * (see PlayerOptions.countIn) — with no rhythm it would be dead air.\n */\nconst leadIn = (schedule: Schedule, spb: number, rhythm: RhythmMode, countIn: boolean): number =>\n countIn && rhythm !== 'none' ? schedule.pickupBeats * spb : 0;\n\n/**\n * Wall-clock length of one play-through — the moment `#arrange` schedules the\n * auto-stop, so a progress bar built on it hits 100% exactly when the player\n * stops. The trailing `+ spb` is the matra the last note rings into.\n */\nfunction playDurationSec(schedule: Schedule, spb: number, rhythm: RhythmMode, countIn: boolean): number {\n return schedule.totalBeats * spb + leadIn(schedule, spb, rhythm, countIn) + spb;\n}\n\n/**\n * Wait for sample buffers, but never let one bad URL strand playback.\n * `Tone.loaded()` rejects as soon as any buffer fails, so an unreachable\n * accompaniment sample (CDN down, wrong `soundsBaseUrl`, a taal with no\n * recorded loop at that tempo) would otherwise leave `play()` hung in the\n * `loading` state with nothing sounding — including the melody, which loaded\n * fine. Warn and carry on: the voices that did load still play.\n */\nasync function loadedOrWarn(Tone: ToneModule): Promise<void> {\n try {\n await Tone.loaded();\n } catch (err) {\n console.warn('[swaralipi] some audio samples failed to load; continuing without them', err);\n }\n}\n\nexport interface BindSheetOptions {\n /** Keep the active note visible while playing by calling `scrollIntoView`\n * on it. `true` → `'center'` (keeps the note's lyric, rendered just below it,\n * on screen too); or pass an explicit block position (`'nearest'`, `'start'`,\n * …). Default off so it never fights a host that manages its own scrolling.\n * Works through the shadow boundary, so it scrolls the page, not just the\n * sheet. */\n autoScroll?: boolean | ScrollLogicalPosition;\n}\n\n/** The common melody-voice call the scheduler needs — both melody instruments\n * are `Tone.Sampler`s, but this keeps the call site decoupled from the class. */\ninterface MelodyVoice {\n triggerAttackRelease(note: string, duration: number, time: number): unknown;\n releaseAll(time?: number): unknown;\n}\n\nexport class SwaralipiPlayer {\n #opts: Required<\n Omit<\n PlayerOptions,\n | 'soundsBaseUrl'\n | 'pianoBaseUrl'\n | 'customInstruments'\n | 'onHighlight'\n | 'onLoop'\n | 'onEvent'\n | 'onBeat'\n | 'onState'\n | 'onLimit'\n | 'tonic'\n | 'bpm'\n | 'laySpeeds'\n >\n > & {\n soundsBaseUrl?: string;\n pianoBaseUrl?: string;\n customInstruments?: Record<string, InstrumentDef>;\n tonic?: string;\n laySpeeds?: LaySpeeds;\n /** Pinned constructor tempo: overrides meta.bpm, survives load(). */\n bpm?: number;\n onHighlight?: (path: string | null, yourTurn?: boolean) => void;\n onLoop?: (state: PracticeState) => void;\n onEvent?: (path: string | null) => void;\n onBeat?: (beatInCycle: number) => void;\n onState?: (state: PlayerState) => void;\n onLimit?: () => void;\n };\n /** Per-song setBpm tweak: beats meta.bpm but is cleared by the next load(). */\n #bpmTweak: number | undefined;\n #doc: Swaralipi | undefined;\n /** Play only these stretches of the song's text (see `load`). */\n #excerpt: Excerpt | undefined;\n /** Taal mode (`loadTaal`): loops one avartan of this taal's theka with no\n * melody. Mutually exclusive with `#doc`. */\n #taal: Taal | undefined;\n #state: PlayerState = 'idle';\n\n #tone: ToneModule | undefined;\n /** Master bus everything routes through, so stop() can fade it out. */\n #master: Gain | undefined;\n /** Cached melody samplers keyed by instrument id, with the MIDI range each\n * was loaded for (rebuilt when a song needs a wider range). */\n #samplers = new Map<string, { sampler: Sampler; lo: number; hi: number }>();\n /** Raw sample buffers for the মীড় glide voice, keyed like #samplers. */\n #glide = new Map<string, { buffers: ToneAudioBuffers; urls: Record<string, string>; lo: number; hi: number }>();\n #tanpura: Players | undefined;\n #tanpuraKey = '';\n #metronome: Player | undefined;\n /** The looping tabla — one loop per লয় segment, each a `GrainPlayer` when\n * the tonic needs retuning or the segment's tempo needs stretching.\n * `fileSpb` is the recorded loop's OWN beat length, which is the unit\n * `quantizeLoopEnd` must snap in (loop points are buffer time). */\n #tabla: { loop: Player | GrainPlayer; fileSpb: number }[] = [];\n #grain: ReturnType<typeof seekableGrain> | undefined;\n #drums: Players | undefined;\n #scheduleIds: number[] = [];\n #fadeTimer: ReturnType<typeof setTimeout> | undefined;\n\n /* Practice: where the playhead is, what repeats, whose turn it is. */\n /** The last note played or sought — what \"this line\" means to the controls. */\n #cursor: string | null = null;\n /** The cursor as an event index: which pass of a line sung more than once. */\n #at = -1;\n /** Where the next fresh play() starts (a seek made while stopped). */\n #startAt: number | null = null;\n #loop: LineRange | null = null;\n /** The repeat as line indices, the passes it holds. */\n #span: [number, number] | null = null;\n #echo = false;\n /** With echo on, every other pass is the learner's: the melody rests. */\n #turn = false;\n /** The arranged timeline, so a seek or a loop can be placed while playing. */\n #timeline: { schedule: Schedule; lines: Line[]; spb: number; shift: number } | undefined;\n /** Listeners on the bound sheet, removed on rebind. */\n #unbind: AbortController | undefined;\n #sheet: HighlightTarget | undefined;\n /** The bound sheet's highlight — beside, never instead of, the consumer's `onHighlight`. */\n #paint: ((path: string | null, yourTurn: boolean) => void) | undefined;\n /** Preview cap, counted in listening time so a seek or a loop can't dodge it. */\n #listened = 0;\n #listenedSince = 0;\n #limitId: number | undefined;\n\n constructor(options: PlayerOptions = {}) {\n this.#opts = {\n soundsBaseUrl: options.soundsBaseUrl ?? DEFAULT_SOUNDS_BASE,\n pianoBaseUrl: options.pianoBaseUrl,\n customInstruments: options.customInstruments,\n tonic: options.tonic,\n bpm: options.bpm,\n laySpeeds: options.laySpeeds,\n baseOctave: options.baseOctave ?? 4,\n instrument: options.instrument ?? 'piano',\n instruments: options.instruments ?? Object.keys(INSTRUMENTS),\n rhythm: options.rhythm ?? 'tabla',\n countIn: options.countIn ?? false,\n tanpura: options.tanpura ?? true,\n repeats: options.repeats ?? true,\n previewLimitSec: options.previewLimitSec ?? Infinity,\n onHighlight: options.onHighlight,\n onLoop: options.onLoop,\n onEvent: options.onEvent,\n onBeat: options.onBeat,\n onState: options.onState,\n onLimit: options.onLimit,\n };\n }\n\n /* ----------------------------------------------------------------- */\n /* Public getters */\n /* ----------------------------------------------------------------- */\n\n get state(): PlayerState {\n return this.#state;\n }\n get bpm(): number {\n return this.#bpmTweak ?? this.#opts.bpm ?? this.#doc?.meta.bpm ?? 90;\n }\n /** The preview cap in seconds (`Infinity` = unlimited). */\n get previewLimitSec(): number {\n return this.#opts.previewLimitSec;\n }\n get instrument(): InstrumentId {\n return this.#effectiveInstrument();\n }\n get instruments(): InstrumentId[] {\n return [...this.#opts.instruments];\n }\n /** The taal currently driving the rhythm (auto from the doc, or an override). */\n get taalId(): TaalId | undefined {\n return this.#taalId();\n }\n /** Whether the effective rhythm will actually be a sampled tabla. */\n get usesTabla(): boolean {\n const id = this.#taalId();\n return this.#opts.rhythm === 'tabla' && id !== undefined && SAMPLED_TAALS.has(id) && !!this.#opts.soundsBaseUrl;\n }\n\n /**\n * Length of one play-through in seconds, for a progress bar (the OS media\n * session's, typically). Derived from the loaded notation on every read and\n * never stored, because every input can move: re-engrave the document, drag\n * the tempo, switch the rhythm off, and this changes with it. `Infinity` in\n * taal mode (one avartan looping, no end — the value the Media Session spec\n * reserves for exactly that), 0 with nothing loaded, and clamped by a preview\n * cap when one is set, since that is when playback will really stop.\n */\n get durationSec(): number {\n if (this.#taal !== undefined) return Infinity;\n if (this.#doc === undefined) return 0;\n const full = playDurationSec(\n buildSchedule(this.#doc, this.#scheduleOpts()),\n 60 / this.#effectiveBpm(),\n this.#opts.rhythm,\n this.#opts.countIn,\n );\n return Math.min(full, this.#opts.previewLimitSec);\n }\n\n /** Seconds played so far, off the Transport's own clock — so it holds while\n * paused, and reads 0 before the first play and after stop(). */\n get positionSec(): number {\n return Math.max(this.#tone?.getTransport().seconds ?? 0, 0); // ≥ 0 through the start pre-roll\n }\n\n /** The note last played or sought (`part.row.note`), or null. */\n get cursor(): string | null {\n return this.#cursor;\n }\n /** The repeated lines, or null. */\n get loop(): LineRange | null {\n return this.#loop && { ...this.#loop };\n }\n /** Whether each repeat is followed by a silent pass for the learner. */\n get echo(): boolean {\n return this.#echo;\n }\n /** Whether the rhythm leads a pickup in (see PlayerOptions.countIn). */\n get countIn(): boolean {\n return this.#opts.countIn;\n }\n\n /* ----------------------------------------------------------------- */\n /* Loading + transport control */\n /* ----------------------------------------------------------------- */\n\n /** Set the document to play. Stops any current playback. With `excerpt`,\n * only the notes singing those stretches of the song's text play, in order\n * (see `alignLyrics`); the length, seeks and repeats all keep to them. */\n load(doc: Swaralipi, { excerpt }: { excerpt?: Excerpt } = {}): void {\n this.#halt();\n this.#doc = doc;\n this.#excerpt = excerpt;\n this.#taal = undefined;\n this.#taalOverride = undefined;\n this.#bpmTweak = undefined; // per-song tweak does not carry across songs\n this.#resetPractice();\n this.#setState('ready');\n }\n\n /**\n * Taal mode: loop one avartan of a taal's theka (rhythm only, no melody) —\n * for a standalone theka player. `play()` loops indefinitely (tabla loop /\n * drum sequence) and fires `onBeat(beatInCycle)` once per matra on the draw\n * thread so the consumer can highlight the active bol / drum-staff note. The\n * taal's `id` should be a sampled taal (see `SAMPLED_TAALS`) for tabla audio;\n * `variation` picks a tabla loop variation. Stops any current playback.\n */\n loadTaal(taal: Taal): void {\n this.#halt();\n this.#taal = taal;\n this.#doc = undefined;\n this.#taalOverride = undefined;\n this.#bpmTweak = undefined;\n this.#resetPractice();\n this.#setState('ready');\n }\n\n /** Start (or resume) playback — from `from` (`part.row.note`, or `part.row`\n * for a line's start) when given, which also jumps there mid-play. Must be\n * triggered from a user gesture so the browser permits `AudioContext`\n * resume. */\n async play(from?: string): Promise<void> {\n if (this.#doc === undefined && this.#taal === undefined) return;\n if (from !== undefined) this.seek(from);\n // Still loading: the seek above has already moved where it will start.\n if (this.#state === 'playing' || this.#state === 'loading') return;\n const resume = this.#state === 'paused';\n // A fresh start claims 'loading' before its first await, so a second tap\n // while Tone downloads only moves the start instead of arranging twice.\n if (!resume) this.#setState('loading');\n let Tone: ToneModule;\n try {\n Tone = await this.#ensureTone();\n await Tone.start();\n } catch (err) {\n if (!resume) this.#setState('ready');\n throw err;\n }\n\n if (resume) {\n Tone.getTransport().start();\n this.#setState('playing');\n this.#armLimit();\n return;\n }\n\n // Fresh start — abort any in-flight stop fade and clear a left-running\n // transport before re-arranging. Only a running one: Tone's stop() on a\n // stopped clock cancels the earlier stop and re-stops now, which revives\n // the last run in between, and its stray ticks could swallow the first\n // note of this one.\n this.#cancelFade();\n const transport = Tone.getTransport();\n if (transport.state !== 'stopped') transport.stop();\n await this.#arrange(Tone);\n transport.start(undefined, this.#startSec() - this.#preroll());\n this.#startAt = null;\n this.#setState('playing');\n this.#armLimit();\n }\n\n /** Pause; `play()` resumes from the same position. */\n pause(): void {\n if (this.#tone === undefined || this.#state !== 'playing') return;\n this.#tone.getTransport().pause();\n this.#disarmLimit();\n this.#setState('paused');\n }\n\n /**\n * Move the playhead to `path` (`part.row.note`, or `part.row` for a line's\n * start). Playing, it jumps and keeps playing; paused or stopped, the next\n * `play()` starts there. A repeat follows the playhead: seeking outside the\n * repeated lines moves the repeat to the new line.\n */\n seek(path: string): void {\n const plan = this.#plan();\n if (plan !== undefined) this.#seekTo(plan, eventAt(plan.schedule.events, path, this.#at));\n }\n\n /** seek(), by event index — the pass, not just the line. */\n #seekTo(plan: { schedule: Schedule; lines: Line[] }, i: number): void {\n if (i < 0) return;\n const at = plan.schedule.events[i]!.path;\n this.#cursor = at;\n this.#at = i;\n this.#turn = false;\n const k = lineAt(plan.lines, i);\n const [a, b] = this.#loopSpan();\n if (this.#span !== null && (k < a || k > b)) this.#setSpan(plan.lines, k, k);\n this.#emitLoop();\n if (this.#timeline !== undefined && (this.#state === 'playing' || this.#state === 'paused')) {\n this.#applyLoop();\n this.#jump(this.#eventSec(i));\n if (this.#state === 'paused') this.#emitHighlight(at);\n } else {\n this.#startAt = i;\n this.#emitHighlight(at);\n }\n }\n\n /**\n * Repeat lines `from`..`to` (`part.row`, either order, inclusive; `to`\n * defaults to `from`). With no argument, the line under the playhead.\n * `null` stops repeating, and ends the sing-back with it. A playhead\n * outside the new repeat moves to its start; live while playing.\n */\n setLoop(from?: string | null, to?: string): void {\n this.#turn = false;\n if (from === null) {\n this.#span = this.#loop = null;\n this.#echo = false;\n this.#applyLoop();\n this.#emitLoop();\n return;\n }\n const plan = this.#plan();\n if (plan === undefined || plan.lines.length === 0) return;\n const { lines } = plan;\n const here = this.#at < 0 ? -1 : lineAt(lines, this.#at);\n const a = from === undefined ? Math.max(here, 0) : this.#lineOf(lines, from, here);\n this.#repeat(plan, a, to === undefined ? a : this.#lineOf(lines, to, a));\n }\n\n /** Repeat lines a..b (indices, either order); the playhead joins them. */\n #repeat(plan: { schedule: Schedule; lines: Line[] }, a: number, b: number): void {\n this.#setSpan(plan.lines, a, b);\n const [lo, hi] = this.#loopSpan();\n const here = this.#at < 0 ? -1 : lineAt(plan.lines, this.#at);\n if (here < lo || here > hi) return this.#seekTo(plan, plan.lines[lo]!.first);\n this.#applyLoop();\n this.#emitLoop();\n }\n\n /** The repeat's passes, and the rows they cover for the sheet's shading —\n * written order, since a span can cross a jump back to an earlier row. */\n #setSpan(lines: Line[], a: number, b: number): void {\n this.#span = [Math.min(a, b), Math.max(a, b)];\n const rows = lines.slice(this.#span[0], this.#span[1] + 1).map((line) => line.row).sort(byRow);\n this.#loop = { from: rows[0]!, to: rows.at(-1)! };\n }\n\n /** The line `path` names, at its pass nearest line `near`; the last line\n * when nothing sounds from there on. */\n #lineOf(lines: Line[], path: string, near: number): number {\n const k = lineFor(lines, path, near);\n return k < 0 ? lines.length - 1 : k;\n }\n\n /**\n * Follow every pass of the repeat with a silent one: the tabla and tanpura\n * keep time and the highlight keeps moving, but the melody rests so the\n * learner can sing the line back — the teacher sings, the student answers.\n * Turning it on with nothing repeating repeats the current line.\n */\n setEcho(on: boolean): void {\n this.#echo = on;\n this.#turn = false;\n if (on && this.#loop === null) this.setLoop();\n else this.#emitLoop();\n }\n\n /**\n * Move by whole lines. Like a player's previous-track button, a step back\n * from more than a matra into the line restarts that line first.\n * `±Infinity` goes to the first / last line.\n */\n stepLine(delta: number): void {\n const plan = this.#plan();\n if (plan === undefined || plan.lines.length === 0) return;\n const { lines, schedule } = plan;\n // No cursor yet: a step down lands on the first line.\n const k = this.#at < 0 ? -1 : lineAt(lines, this.#at);\n const into = k < 0 ? 0 : schedule.events[this.#at]!.beat - lines[k]!.beat;\n const step = delta < 0 && this.#state === 'playing' && into > 1 ? delta + 1 : delta;\n this.#seekTo(plan, lines[Math.min(Math.max(k + step, 0), lines.length - 1)]!.first);\n }\n\n /** Move by single notes (rests and holds included — each is a column). */\n stepNote(delta: number): void {\n const plan = this.#plan();\n const events = plan?.schedule.events ?? [];\n let i = this.#at;\n for (let left = Math.abs(delta); left > 0; left--) {\n do i += Math.sign(delta);\n while (events[i]?.glide === true);\n }\n if (plan !== undefined && events.length > 0) this.#seekTo(plan, Math.min(Math.max(i, 0), events.length - 1));\n }\n\n /**\n * Stop and rewind to the start. When sounding, the accompaniment (tabla /\n * metronome / tanpura, which otherwise loop) is gently faded out over\n * STOP_FADE_SEC before the transport is halted, so the rhythm doesn't keep\n * playing or cut abruptly; otherwise it halts immediately.\n */\n stop(): void {\n this.#disarmLimit();\n this.#listened = 0;\n this.#startAt = null;\n if (this.#turn) {\n this.#turn = false;\n this.#emitLoop();\n }\n if (this.#tone === undefined || this.#state === 'idle') {\n this.#halt();\n return;\n }\n if ((this.#state === 'playing' || this.#state === 'paused') && this.#master !== undefined) {\n const now = this.#tone.now();\n this.#master.gain.cancelScheduledValues(now);\n this.#master.gain.rampTo(0, STOP_FADE_SEC, now);\n this.#emitHighlight(null);\n this.#setState(this.#doc || this.#taal ? 'ready' : 'idle');\n this.#cancelFadeTimer();\n this.#fadeTimer = setTimeout(() => this.#halt(), STOP_FADE_SEC * 1000 + 60);\n return;\n }\n this.#halt();\n }\n\n /** Immediate, synchronous teardown: stop+rewind the transport, kill the\n * looping accompaniment, restore the master gain for the next play. */\n #halt(): void {\n this.#cancelFadeTimer();\n this.#disarmLimit();\n this.#timeline = undefined;\n this.#fence = 0;\n if (this.#tone !== undefined) {\n const transport = this.#tone.getTransport();\n transport.stop();\n transport.cancel(0);\n transport.position = 0;\n transport.loop = false;\n }\n // Dispose the looping tabla outright — a synced loop can outlive a bare\n // transport.stop(); #arrange recreates it on the next play.\n this.#disposeTabla();\n this.#restoreMasterGain();\n this.#scheduleIds = [];\n this.#emitHighlight(null);\n if (this.#state !== 'idle') this.#setState(this.#doc || this.#taal ? 'ready' : 'idle');\n }\n\n #cancelFadeTimer(): void {\n if (this.#fadeTimer !== undefined) {\n clearTimeout(this.#fadeTimer);\n this.#fadeTimer = undefined;\n }\n }\n\n /** Abort an in-flight stop-fade (timer + gain ramp) without touching the\n * transport — used when play() interrupts a fade. */\n #cancelFade(): void {\n this.#cancelFadeTimer();\n this.#restoreMasterGain();\n }\n\n #disposeTabla(): void {\n for (const { loop } of this.#tabla) loop.dispose();\n this.#tabla = [];\n }\n\n /** Snap each loop to a whole number of ITS OWN beats now the buffer length is\n * known, so a mistrimmed file phase-locks instead of drifting. */\n #quantizeTablaLoops(): void {\n for (const { loop, fileSpb } of this.#tabla) {\n if (loop.buffer?.loaded) loop.loopEnd = quantizeLoopEnd(loop.buffer.duration, fileSpb);\n }\n }\n\n /** Count down whatever listening time the preview cap has left. On the\n * audio clock, which keeps running while the page is hidden. */\n #armLimit(): void {\n const left = this.#opts.previewLimitSec - this.#listened;\n const context = this.#tone?.getContext();\n if (!Number.isFinite(left) || context === undefined) return;\n this.#listenedSince = context.now();\n this.#limitId = context.setTimeout(() => {\n this.#limitId = undefined;\n if (this.#state !== 'playing') return;\n this.stop();\n this.#opts.onLimit?.();\n }, Math.max(left, 0));\n }\n\n #disarmLimit(): void {\n const context = this.#tone?.getContext();\n if (this.#limitId === undefined || context === undefined) return;\n context.clearTimeout(this.#limitId);\n this.#limitId = undefined;\n this.#listened += context.now() - this.#listenedSince;\n }\n\n #restoreMasterGain(): void {\n if (this.#master !== undefined && this.#tone !== undefined) {\n this.#master.gain.cancelScheduledValues(this.#tone.now());\n this.#master.gain.value = 1;\n }\n }\n\n /* ----------------------------------------------------------------- */\n /* Settings (re-arrange from the top if mid-playback) */\n /* ----------------------------------------------------------------- */\n\n setTonic(tonic: string): void {\n this.#opts.tonic = tonic;\n this.#reapply();\n }\n setBpm(bpm: number): void {\n this.#bpmTweak = bpm;\n this.#reapply();\n }\n /** Update the preview cap (`Infinity` lifts it). Takes effect on next play. */\n setPreviewLimit(sec: number): void {\n this.#opts.previewLimitSec = sec;\n }\n setInstrument(instrument: InstrumentId): void {\n this.#opts.instrument = instrument;\n this.#reapply();\n }\n setRhythm(rhythm: RhythmMode): void {\n this.#opts.rhythm = rhythm;\n this.#reapply();\n }\n /** Rhythm first (true) or the melody first (false) — see PlayerOptions.countIn. */\n setCountIn(on: boolean): void {\n this.#opts.countIn = on;\n this.#reapply();\n }\n setTanpura(on: boolean): void {\n this.#opts.tanpura = on;\n this.#reapply();\n }\n /** Override the taal (null restores auto-detection from `meta.taal`). */\n setTaal(id: TaalId | null): void {\n this.#taalOverride = id ?? undefined;\n this.#taalAuto = id === null;\n this.#reapply();\n }\n\n /**\n * Wire highlight output to a `<swaralipi-sheet>` (or any highlight target).\n * Pass `{ autoScroll }` to keep the active note in view while playing.\n *\n * A sheet element also becomes the practice surface: a tap on a line plays\n * from the note under it (Shift stretches the repeat to that line), and\n * while it has focus — only then, so no key is taken from the page — Space\n * plays/pauses, ↑/↓ move by line, ←/→ by note, Home/End jump to the first /\n * last line, R repeats the line, T turns sing-back on/off, Esc stops the\n * repeat and Shift+↑/↓ stretch it. To gate a tap-to-play (a play quota, say),\n * `preventDefault()` its `swaralipi-seek` event in a capturing listener.\n */\n bindSheet(target: HighlightTarget, opts: BindSheetOptions = {}): void {\n // 'center' so the lyric directly below the note stays on screen too\n // ('nearest' can park the note at the bottom edge, hiding its lyric).\n const block: ScrollLogicalPosition | undefined =\n opts.autoScroll === true ? 'center' : opts.autoScroll || undefined;\n this.#paint = (path, yourTurn) => {\n target.clearHighlights();\n if (path === null) return;\n const el = target.highlight(path, yourTurn);\n if (block !== undefined && el !== null) {\n el.scrollIntoView({ block, inline: 'nearest', behavior: 'smooth' });\n }\n };\n this.#sheet = target;\n target.markLoop?.(this.#loop, this.#turn);\n this.#unbind?.abort();\n // The creator's canvas is a plain object: highlights only.\n if (!(target instanceof EventTarget)) return;\n const el = target as HighlightTarget & HTMLElement;\n const { signal } = (this.#unbind = new AbortController());\n el.setAttribute('seekable', '');\n signal.addEventListener('abort', () => el.removeAttribute('seekable'));\n el.addEventListener('swaralipi-seek', (e) => this.#onTap(e as SeekEvent), { signal });\n el.addEventListener('keydown', (e) => this.#onKey(e), { signal });\n }\n\n #onTap(e: SeekEvent): void {\n if (e.defaultPrevented) return;\n if (e.detail.extend) this.#extendLoop(e.detail.path);\n else void this.play(e.detail.path);\n }\n\n #onKey(e: KeyboardEvent): void {\n if (e.ctrlKey || e.metaKey || e.altKey) return;\n const shift = e.shiftKey;\n // Letters by physical key, so a Bengali or Hindi keyboard layout works too.\n const act: Record<string, (() => void) | undefined> = {\n Space: () => (this.#state === 'playing' ? this.pause() : void this.play()),\n ArrowUp: () => (shift ? this.#extendBy(-1) : this.stepLine(-1)),\n ArrowDown: () => (shift ? this.#extendBy(1) : this.stepLine(1)),\n ArrowLeft: () => this.stepNote(-1),\n ArrowRight: () => this.stepNote(1),\n Home: () => this.stepLine(-Infinity),\n End: () => this.stepLine(Infinity),\n KeyR: () => this.setLoop(this.#loop === null ? undefined : null),\n KeyT: () => this.setEcho(!this.#echo),\n Escape: this.#loop === null ? undefined : () => this.setLoop(null),\n };\n const run = act[e.code];\n if (run === undefined) return;\n e.preventDefault();\n run();\n }\n\n /** Grow the repeat (or start one from the current line) to take in `path`'s line. */\n #extendLoop(path: string): void {\n const plan = this.#plan();\n if (plan === undefined || plan.lines.length === 0) return;\n const here = this.#at < 0 ? -1 : lineAt(plan.lines, this.#at);\n const k = this.#lineOf(plan.lines, path, here);\n const [a, b] = this.#span ?? (here < 0 ? [k, k] : [here, here]);\n this.#repeat(plan, Math.min(a, k), Math.max(b, k));\n }\n\n /** Shift+↑/↓: one more line above / below the repeat. */\n #extendBy(delta: number): void {\n const plan = this.#plan();\n if (plan === undefined || plan.lines.length === 0) return;\n const here = this.#at < 0 ? 0 : lineAt(plan.lines, this.#at);\n const [a, b] = this.#span ?? [here, here];\n const k = Math.min(Math.max((delta < 0 ? a : b) + delta, 0), plan.lines.length - 1);\n this.#repeat(plan, Math.min(a, k), Math.max(b, k));\n }\n\n /**\n * Check whether an instrument's samples are reachable (its CDN is up / the\n * local files exist), via a one-byte ranged fetch of a representative sample.\n * A pass means Tone can actually load it. `false` for unknown ids, local\n * instruments with no `soundsBaseUrl`, or any network failure/timeout.\n */\n async checkInstrument(id: string, timeoutMs?: number): Promise<boolean> {\n const def = this.#resolveDef(id);\n if (def === undefined) return false;\n const url = instrumentSampleUrl(def, this.#opts.soundsBaseUrl);\n if (url === undefined) return false;\n return probeUrl(url, timeoutMs);\n }\n\n /**\n * Probe several instruments at once (default: the exposed `instruments`),\n * returning `{ id: available }`. Use it to disable picker options whose CDN\n * or files are down. Probes run concurrently; a check never throws.\n */\n async checkInstruments(\n ids: string[] = this.#opts.instruments,\n timeoutMs?: number,\n ): Promise<Record<string, boolean>> {\n const entries = await Promise.all(\n ids.map(async (id) => [id, await this.checkInstrument(id, timeoutMs)] as const),\n );\n return Object.fromEntries(entries);\n }\n\n /** Release all audio resources. The instance is unusable afterward. */\n dispose(): void {\n this.#halt();\n this.#unbind?.abort();\n this.#tone?.getTransport().off('loop', this.#onPass);\n for (const { sampler } of this.#samplers.values()) sampler.dispose();\n this.#samplers.clear();\n for (const { buffers } of this.#glide.values()) buffers.dispose();\n this.#glide.clear();\n this.#tanpura?.dispose();\n this.#metronome?.dispose();\n this.#disposeTabla();\n this.#drums?.dispose();\n this.#master?.dispose();\n this.#tanpura = this.#metronome = this.#drums = this.#master = undefined;\n }\n\n /* ----------------------------------------------------------------- */\n /* Internals */\n /* ----------------------------------------------------------------- */\n\n #taalOverride: TaalId | undefined;\n #taalAuto = true;\n\n #setState(state: PlayerState): void {\n this.#state = state;\n this.#opts.onState?.(state);\n }\n\n #emitHighlight(path: string | null, yourTurn = false): void {\n this.#paint?.(path, yourTurn);\n this.#opts.onHighlight?.(path, yourTurn);\n }\n\n #emitLoop(): void {\n this.#opts.onLoop?.({ loop: this.loop, echo: this.#echo, yourTurn: this.#turn });\n this.#sheet?.markLoop?.(this.#loop, this.#turn);\n }\n\n /** A new document starts with nothing repeated, from the top. */\n #resetPractice(): void {\n this.#cursor = this.#startAt = this.#loop = this.#span = null;\n this.#at = -1;\n this.#echo = this.#turn = false;\n this.#listened = 0;\n this.#emitLoop();\n }\n\n /** The timeline to navigate: the arranged one while playing, else built\n * fresh — it is pure and cheap, and a stopped player may have a new tonic\n * or tempo since. */\n #plan(): { schedule: Schedule; lines: Line[] } | undefined {\n if (this.#timeline !== undefined) return this.#timeline;\n if (this.#doc === undefined) return undefined;\n const schedule = buildSchedule(this.#doc, this.#scheduleOpts());\n return { schedule, lines: scheduleLines(schedule) };\n }\n\n /** The repeat as line indices (`[0, -1]`, i.e. empty, when off). */\n #loopSpan(): [number, number] {\n return this.#span ?? [0, -1];\n }\n\n /** The repeat's lines on the arranged timeline, cached for the per-note\n * checks (#hears), which run on every note. */\n #loopLines: [number, number] = [0, -1];\n\n /** Whether line `k` may sound: any line, unless a repeat holds others. */\n #hears(k: number): boolean {\n return this.#loop === null || (k >= this.#loopLines[0] && k <= this.#loopLines[1]);\n }\n\n /** Transport seconds of event `i`, pulled back by its কণ so the grace is\n * heard too. */\n #eventSec(i: number): number {\n const { schedule, spb, shift } = this.#timeline!;\n const ev = schedule.events[i]!;\n return Math.max((ev.beat - GRACE_STEP * ev.kan.length) * spb + shift, 0);\n }\n\n /** The repeat in transport seconds: from its first note's own start (its\n * কণ included) for exactly the lines' length, so every pass keeps the\n * tabla's phase. */\n #loopSec(): [number, number] {\n const { lines, spb } = this.#timeline!;\n const [a, b] = this.#loopLines;\n const start = this.#eventSec(lines[a]!.first);\n return [start, start + (lines[b]!.endBeat - lines[a]!.beat) * spb];\n }\n\n /** Put the repeat on the transport, or take it off. */\n #applyLoop(): void {\n const transport = this.#tone?.getTransport();\n if (transport === undefined || this.#timeline === undefined) return;\n this.#loopLines = this.#loopSpan();\n if (this.#span === null) {\n transport.loop = false;\n return;\n }\n transport.setLoopPoints(...this.#loopSec());\n transport.loop = true;\n }\n\n /** Where a fresh play() starts: a seek made while stopped, else the repeat,\n * else the top. */\n #startSec(): number {\n const events = this.#timeline?.schedule.events ?? [];\n if (this.#startAt !== null) return this.#eventSec(Math.min(this.#startAt, events.length - 1));\n return this.#span === null ? 0 : this.#loopSec()[0];\n }\n\n /** Move the transport; notes still ringing from the old place are let go. */\n #jump(sec: number): void {\n // Tone moves the position on its next tick, but the clock has not yet\n // walked the sliver of old timeline before it, so a note due there would\n // still sound ahead of the one just asked for. The fence drops those.\n const Tone = this.#tone!;\n const transport = Tone.getTransport();\n this.#fence = Tone.now();\n // A repeat wrapping in that same sliver would undo the jump outright: the\n // wrap resets Tone's tick offsets from its own moment on, the jump's\n // included. So no wrap until the jump has landed.\n if (transport.loop) {\n transport.loopEnd = this.#loopSec()[1] + 3600;\n Tone.getContext().setTimeout(() => this.#applyLoop(), 0.15);\n }\n transport.seconds = sec - this.#preroll();\n this.#voice?.releaseAll();\n }\n\n /** Audio time before which a note callback belongs to the timeline a seek\n * just left (see #jump). */\n #fence = 0;\n\n /** START_PREROLL_SEC in whole transport ticks: an offset between ticks\n * would shift every later repeat wrap by the remainder — measured, a\n * 0.8 ms splice in the tabla at each pass. */\n #preroll(): number {\n const transport = this.#tone!.getTransport();\n const perSec = (transport.bpm.value / 60) * transport.PPQ;\n return Math.ceil(START_PREROLL_SEC * perSec) / perSec;\n }\n\n /** The melody voice of the arrangement, for #jump. */\n #voice: MelodyVoice | undefined;\n\n /** The repeat wrapped. With sing-back on, the turn passes between the\n * player and the learner; the sheet is told at the wrap itself. */\n #onPass = (time: number): void => {\n if (this.#loop === null || !this.#echo) return;\n this.#turn = !this.#turn;\n this.#tone?.getDraw().schedule(() => this.#emitLoop(), time);\n };\n\n /** The taal one accompaniment segment plays: taal mode's, an explicit\n * setTaal override (pinned across the whole song, তালফেরতা included), else\n * the segment's own. `null` = a মুক্তছন্দ passage. */\n #segmentTaal(seg: TempoSegment): Taal | null | undefined {\n if (this.#taal !== undefined) return this.#taal;\n if (!this.#taalAuto && this.#taalOverride !== undefined) return TAALS[this.#taalOverride];\n return seg.taal;\n }\n\n /** The tabla variation to play: taal-mode taal's, the segment's own (auto\n * mode), else none — an explicit setTaal override plays the default variation. */\n #variation(taal: Taal | null | undefined): string | undefined {\n if (this.#taal !== undefined) return this.#taal.variation;\n return this.#taalAuto ? taal?.variation : undefined;\n }\n\n /** Resolve the active taal id: taal mode's taal, an explicit override, else\n * the doc's opening one (a তালফেরতা doc may carry it on its first row) — but\n * only when it names a sampled taal. */\n #taalId(): TaalId | undefined {\n const opening = this.#doc?.parts[0]?.rows[0]?.taal || this.#doc?.meta.taal;\n const id = this.#taal?.id ?? (!this.#taalAuto && this.#taalOverride !== undefined ? this.#taalOverride : opening?.id);\n return id !== undefined && id in TAALS ? (id as TaalId) : undefined;\n }\n\n /** Resolve an instrument id to its def (custom overrides built-ins; the\n * `pianoBaseUrl` shortcut self-hosts the built-in piano). */\n #resolveDef(id: string): InstrumentDef | undefined {\n const custom = this.#opts.customInstruments?.[id];\n if (custom) return custom;\n const def = INSTRUMENTS[id];\n if (def && id === 'piano' && this.#opts.pianoBaseUrl) {\n return { ...def, baseUrl: normalizeBase(this.#opts.pianoBaseUrl) };\n }\n return def;\n }\n\n /** A CDN-backed instrument that needs no `soundsBaseUrl` — used when the\n * chosen one is local-only and no samples host is set, or is unknown. */\n #fallbackInstrument(): string {\n const exposed = this.#opts.instruments.find((id) => {\n const d = this.#resolveDef(id);\n return d !== undefined && d.local !== true;\n });\n return exposed ?? 'harmonium';\n }\n\n /** The instrument actually used: the chosen one, unless it's local-only with\n * no `soundsBaseUrl` (or unknown), in which case a CDN fallback. */\n #effectiveInstrument(): string {\n const id = this.#opts.instrument;\n const def = this.#resolveDef(id);\n if (def === undefined) return this.#fallbackInstrument();\n if (def.local === true && !this.#opts.soundsBaseUrl) return this.#fallbackInstrument();\n return id;\n }\n\n #scheduleOpts() {\n return {\n tonic: this.#opts.tonic,\n baseOctave: this.#opts.baseOctave,\n laySpeeds: this.#opts.laySpeeds,\n repeats: this.#opts.repeats,\n excerpt: this.#excerpt,\n };\n }\n\n /** Effective tempo: snapped to the taal's available tabla tempos while a\n * tabla actually plays (so it never snaps to a bpm that taal lacks). */\n #effectiveBpm(): number {\n const id = this.#taalId();\n return this.usesTabla && id ? nearestTablaBpm(this.bpm, tablaBpms(id)) : this.bpm;\n }\n\n async #ensureTone(): Promise<ToneModule> {\n this.#tone ??= await import('tone');\n return this.#tone;\n }\n\n /** Hard stop → rebuild → restart, only while playing; otherwise just store.\n * Uses #halt (not the stop() fade) so a setting change restarts instantly,\n * from the note it was on — slowing down a repeated line keeps repeating it. */\n #reapply(): void {\n if (this.#state !== 'playing') return;\n const at = this.#at;\n this.#halt();\n this.#startAt = at < 0 ? null : at;\n void this.play();\n }\n\n /** The master bus everything routes through (created once, → destination). */\n #ensureMaster(Tone: ToneModule): Gain {\n this.#master ??= new Tone.Gain(1).toDestination();\n return this.#master;\n }\n\n /** Build the melody instrument(s)/rhythm/drone for the current settings and\n * wait for their buffers, then schedule everything on the Transport. */\n async #arrange(Tone: ToneModule): Promise<void> {\n if (this.#taal !== undefined) return this.#arrangeTaal(Tone);\n if (this.#doc === undefined) return;\n const base = this.#opts.soundsBaseUrl;\n const transport = Tone.getTransport();\n transport.cancel(0);\n transport.position = 0;\n transport.off('loop', this.#onPass).on('loop', this.#onPass);\n this.#scheduleIds = [];\n\n // Fresh master bus at unity gain (a prior stop-fade may have lowered it).\n this.#ensureMaster(Tone);\n this.#restoreMasterGain();\n\n const bpm = this.#effectiveBpm();\n transport.bpm.value = bpm;\n const spb = 60 / bpm;\n\n // Build the (pure) schedule first so the melody sampler loads only the\n // samples covering this song's pitch range — fewer files to fetch.\n const schedule: Schedule = buildSchedule(this.#doc, this.#scheduleOpts());\n const lines = scheduleLines(schedule);\n const range = midiRange(schedule);\n\n // --- melody instrument ---\n const id = this.#effectiveInstrument();\n const def = this.#resolveDef(id) ?? INSTRUMENTS.harmonium!;\n const melody = this.#buildMelody(Tone, id, base, range);\n this.#voice = melody;\n // মীড় voice: only built when the song actually glides somewhere. Must be\n // created here, with the other voices — anything built after the\n // `loadedOrWarn` below would still be downloading when the notes fire.\n const glide = schedule.events.some((ev) => ev.glide === true)\n ? this.#buildGlide(Tone, id, base, range)\n : undefined;\n\n // A pickup either waits for the rhythm (countIn: the melody is pushed\n // later and the rhythm loops from 0, filling the count-in) or goes first\n // (the default: the rhythm comes in on the song's সম). Either way its sam\n // locks to the loop's.\n const shift = leadIn(schedule, spb, this.#opts.rhythm, this.#opts.countIn);\n const entry = this.#opts.countIn ? 0 : schedule.samBeat * spb;\n this.#timeline = { schedule, lines, spb, shift };\n\n // --- rhythm --- (one loop per লয় segment)\n this.#buildRhythm(Tone, transport, base, spb, schedule.tempo, shift, entry);\n\n // --- tanpura drone ---\n this.#buildTanpura(Tone, transport, base, spb, schedule.tempo, shift);\n\n // wait for the (now-minimal) sample set to load before scheduling\n await loadedOrWarn(Tone);\n\n // Snap the tabla loop to a whole number of beats now its buffer length is\n // known, so a mistrimmed loop phase-locks instead of drifting (no-op for a\n // correctly trimmed file).\n this.#quantizeTablaLoops();\n\n // --- notes + highlights ---\n const draw = Tone.getDraw();\n const mediaLead = Math.min(MEDIA_LEAD_SEC, spb); // never more than a matra ahead\n\n // Every note is a persistent transport event (`schedule`, not\n // `scheduleOnce`), so a seek back or a repeat's next pass hears it again.\n // Each asks, as it comes due, whether its line is inside the repeat and\n // whether this pass is the learner's to sing.\n let line = 0;\n schedule.events.forEach((ev, i) => {\n while (lines[line + 1] !== undefined && lines[line + 1]!.first <= i) line++;\n const k = line;\n const heard = (time: number) => time >= this.#fence && this.#hears(k);\n const sounds = (time: number) => heard(time) && !this.#turn;\n const at = ev.beat * spb + shift;\n // A glide target is sounded by the attack it slides from, not on its own.\n if (ev.glide !== true) {\n for (const g of graceTouches(ev)) {\n const graceName = midiToSampleName(g.midi);\n transport.schedule((time) => {\n if (sounds(time)) melody.triggerAttackRelease(graceName, spb * 0.4, time);\n }, Math.max(g.beat * spb + shift, 0));\n }\n }\n if (ev.midi !== null && ev.glide !== true) {\n const name = midiToSampleName(ev.midi);\n const dur = Math.max(ev.durationBeats * spb, 0.05);\n const targets = glide !== undefined ? glideTargets(schedule.events, i) : [];\n if (targets.length > 0 && glide !== undefined) {\n // Legs are offsets from the attack; the transport hands us the audio\n // time of that attack, which is what the automation must be anchored to.\n const last = targets[targets.length - 1]!;\n const legs = [\n { midi: ev.midi, at: 0 },\n ...targets.map((t) => ({ midi: t.midi!, at: (t.beat - ev.beat) * spb })),\n ];\n const end = (last.beat + last.durationBeats - ev.beat) * spb;\n transport.schedule((time) => {\n if (!sounds(time)) return;\n triggerGlide(\n Tone,\n glide.buffers,\n glide.urls,\n this.#ensureMaster(Tone),\n legs.map((l) => ({ midi: l.midi, at: time + l.at })),\n time + end,\n def.release ?? 1,\n );\n }, at);\n } else {\n transport.schedule((time) => {\n if (sounds(time)) melody.triggerAttackRelease(name, dur, time);\n }, at);\n }\n }\n // Two clocks, deliberately: the audio one (survives a hidden page) carries\n // the line to whatever is not drawing, a beat-fraction early so a lock\n // screen has time to repaint; the draw thread keeps the on-screen\n // highlight exactly on the note.\n if (this.#opts.onEvent !== undefined) {\n transport.schedule((time) => {\n if (heard(time)) this.#opts.onEvent?.(ev.path);\n }, Math.max(at - mediaLead, 0));\n }\n // The learner's pass still moves the highlight: it shows where to sing.\n transport.schedule((time) => {\n if (!heard(time)) return;\n const turn = this.#turn;\n this.#cursor = ev.path;\n this.#at = i;\n draw.schedule(() => this.#emitHighlight(ev.path, turn), time);\n }, at);\n });\n this.#applyLoop();\n\n // clear highlight + auto-stop at the end\n const endAt = playDurationSec(schedule, spb, this.#opts.rhythm, this.#opts.countIn);\n transport.scheduleOnce((time) => {\n this.#opts.onEvent?.(null);\n draw.schedule(() => this.#emitHighlight(null), time);\n }, schedule.totalBeats * spb + shift);\n transport.scheduleOnce(() => this.stop(), endAt);\n }\n\n /** Taal mode: loop one avartan forever (tabla loop / drum sequence via\n * #buildRhythm), firing onBeat + a `String(beatInCycle)` highlight each matra\n * on the draw thread. No melody, no tanpura, no auto-stop — it plays until\n * stop(). */\n async #arrangeTaal(Tone: ToneModule): Promise<void> {\n if (this.#taal === undefined) return;\n const base = this.#opts.soundsBaseUrl;\n const transport = Tone.getTransport();\n transport.cancel(0);\n transport.position = 0;\n this.#scheduleIds = [];\n\n this.#ensureMaster(Tone);\n this.#restoreMasterGain();\n\n const bpm = this.#effectiveBpm();\n transport.bpm.value = bpm;\n const spb = 60 / bpm;\n\n this.#buildRhythm(Tone, transport, base, spb, TAAL_MODE_TEMPO, 0, 0);\n await loadedOrWarn(Tone);\n this.#quantizeTablaLoops();\n\n const draw = Tone.getDraw();\n const n = Math.max(1, this.#taal.numBeats);\n let beat = 0;\n const id = transport.scheduleRepeat((time) => {\n const b = beat % n;\n draw.schedule(() => {\n this.#emitHighlight(String(b));\n this.#opts.onBeat?.(b);\n }, time);\n beat += 1;\n }, spb, 0);\n this.#scheduleIds.push(id);\n }\n\n /** Build (or reuse) the melody sampler for `id`, loading only the samples\n * covering `range`. A cached sampler is reused while it still covers the\n * range; otherwise it's rebuilt (so changing songs/tonic widens it lazily). */\n #buildMelody(\n Tone: ToneModule,\n id: string,\n base: string | undefined,\n range: { lo: number; hi: number } | undefined,\n ): MelodyVoice {\n const def = this.#resolveDef(id) ?? INSTRUMENTS.harmonium!;\n const master = this.#ensureMaster(Tone);\n const cached = this.#samplers.get(id);\n if (cached && (range === undefined || (cached.lo <= range.lo && cached.hi >= range.hi))) {\n return cached.sampler;\n }\n cached?.sampler.dispose();\n const sampler = createSampler(Tone, def, base, range).connect(master);\n this.#samplers.set(id, { sampler, lo: range?.lo ?? -Infinity, hi: range?.hi ?? Infinity });\n return sampler;\n }\n\n /** Build (or reuse) the মীড় glide buffers for `id` — the same samples the\n * Sampler uses, kept as raw buffers so a note can be started once and its\n * playbackRate automated. Cached and range-widened exactly like #buildMelody. */\n #buildGlide(\n Tone: ToneModule,\n id: string,\n base: string | undefined,\n range: { lo: number; hi: number } | undefined,\n ) {\n const cached = this.#glide.get(id);\n if (cached && (range === undefined || (cached.lo <= range.lo && cached.hi >= range.hi))) return cached;\n cached?.buffers.dispose();\n const def = this.#resolveDef(id) ?? INSTRUMENTS.harmonium!;\n const built = createBuffers(Tone, def, base, range);\n const entry = { ...built, lo: range?.lo ?? -Infinity, hi: range?.hi ?? Infinity };\n this.#glide.set(id, entry);\n return entry;\n }\n\n /**\n * Accompaniment, one লয় / তাল segment at a time. A tempo change under the\n * melody is a real tempo change under the drum: the tabla loop is rebuilt at\n * the segment's own bpm — its own recorded file when the set has one at that\n * tempo, else the nearest file time-stretched by `GrainPlayer` (which\n * stretches *without* transposing, unlike a plain playbackRate) — and the\n * click / drum / drone patterns re-space their interval. A তালফেরতা swaps the\n * theka the same way: each segment loops its own taal's file (or pattern, or\n * click cycle), and a মুক্তছন্দ segment rests. A document with neither mark\n * has exactly one segment, so this is the old single-loop path. Nothing\n * sounds before `entry` (transport seconds): the সম a pickup leads into.\n */\n #buildRhythm(\n Tone: ToneModule,\n transport: ReturnType<ToneModule['getTransport']>,\n base: string | undefined,\n spb: number,\n segments: readonly TempoSegment[],\n shift: number,\n entry: number,\n ): void {\n // dispose stale loops so they don't double up after a re-arrange\n this.#disposeTabla();\n\n const master = this.#ensureMaster(Tone);\n const rhythm = this.#opts.rhythm;\n if (rhythm === 'none' || (base === undefined && rhythm !== 'drums')) return;\n\n segments.forEach((seg, i) => {\n const own = this.#segmentTaal(seg);\n // An explicit মুক্তছন্দ passage has no theka to keep: the rhythm rests.\n if (own === null) return;\n const taalId = own !== undefined && own.id in TAALS ? (own.id as TaalId) : undefined;\n // Segment 0 starts at 0 so a count-in fills the pickup, unless the rhythm\n // waits for the সম; the last one is left open-ended so it rings under\n // the final note's tail. A segment the pickup covers whole never sounds.\n const from = Math.max(i === 0 ? 0 : seg.beat * spb + shift, entry);\n const to = i === segments.length - 1 ? Infinity : seg.endBeat * spb + shift;\n if (from >= to) return;\n const beatSec = spb / seg.scale; // seconds per matra inside this segment\n const span = to === Infinity ? undefined : to - from;\n // Which matra of the segment a click lands on, read off the transport\n // rather than counted, so it is still right after a seek or a repeat.\n const beatAt = (time: number) => Math.round((transport.getSecondsAtTime(time) - from) / beatSec);\n\n if (rhythm === 'tabla' && taalId !== undefined && SAMPLED_TAALS.has(taalId) && base !== undefined) {\n const bpm = 60 / beatSec;\n const fileBpm = nearestTablaBpm(bpm, tablaBpms(taalId));\n const rate = bpm / fileBpm;\n // Retune the recorded loop to the song's Sa; an unshifted tonic at a\n // recorded tempo stays on the plain Player (no granulation at all).\n const semis = tablaShiftSemitones(this.#tonicSemitone());\n const url = tablaUrl(base, taalId, fileBpm, this.#variation(own));\n this.#grain ??= seekableGrain(Tone);\n const loop = (rate === 1 && semis === 0\n ? new Tone.Player({ url, loop: true })\n : new this.#grain({\n url,\n loop: true,\n playbackRate: rate,\n detune: semis * 100,\n grainSize: TABLA_GRAIN_SEC,\n overlap: TABLA_GRAIN_OVERLAP_SEC,\n })\n ).connect(master);\n loop.sync().start(from);\n if (span !== undefined) {\n // The next loop starts clean on the boundary (a সম); this one just\n // decays under it instead of being cut mid-skin. Volume automation is\n // audio-clock, so it has to be armed from inside a transport callback\n // — a persistent one that restores the level once the loop has\n // stopped, since a repeat wrapping back brings this segment round again.\n this.#scheduleIds.push(\n transport.schedule((t) => {\n loop.volume.setValueAtTime(0, t);\n loop.volume.linearRampToValueAtTime(-40, t + LAY_TAIL_SEC);\n loop.volume.setValueAtTime(0, t + LAY_TAIL_SEC + 0.05);\n }, to),\n );\n loop.stop(to + LAY_TAIL_SEC);\n }\n this.#tabla.push({ loop, fileSpb: 60 / fileBpm });\n return;\n }\n\n if (rhythm === 'drums') {\n this.#drums ??= createDrumKit(Tone).connect(master);\n const drums = this.#drums;\n // Prefer the canonical TAALS def (has khaali), else the segment's own taal.\n const pattern = drumPattern(this.#taal ?? (taalId !== undefined ? TAALS[taalId] : own) ?? { numBeats: 4, sam: 0 });\n this.#scheduleIds.push(\n transport.scheduleRepeat(\n (time) => {\n const voice = pattern[beatAt(time) % pattern.length]!;\n if (drums.has(voice)) drums.player(voice).start(time);\n },\n beatSec,\n from,\n span,\n ),\n );\n return;\n }\n\n // metronome fallback: a click each beat, louder on sam (cycle start).\n // The segment's own numBeats even when its taal isn't sampled (so a pickup\n // song's sam accent lands right, matching the shift).\n this.#metronome ??= createMetronome(Tone, base!).connect(master);\n const metro = this.#metronome;\n const cycle = (this.#taal ?? seg.taal)?.numBeats ?? 4;\n this.#scheduleIds.push(\n transport.scheduleRepeat(\n (time) => {\n metro.volume.setValueAtTime(beatAt(time) % cycle === 0 ? 0 : -8, time);\n metro.start(time);\n },\n beatSec,\n from,\n span,\n ),\n );\n });\n }\n\n #buildTanpura(\n Tone: ToneModule,\n transport: ReturnType<ToneModule['getTransport']>,\n base: string | undefined,\n spb: number,\n segments: readonly TempoSegment[],\n shift: number,\n ): void {\n if (!this.#opts.tanpura || base === undefined) return;\n\n // Pa–Sa–Sa–Sa drone, one pluck every two beats, cycling.\n const tonicPc = ((this.#tonicSemitone() % 12) + 12) % 12;\n const sa = TANPURA_PCS[tonicPc]!;\n const pa = TANPURA_PCS[(tonicPc + 7) % 12]!;\n\n // Load only the two pitch classes the drone uses (not all 12); rebuild if\n // the tonic changed.\n const key = `${sa},${pa}`;\n if (this.#tanpura === undefined || this.#tanpuraKey !== key) {\n this.#tanpura?.dispose();\n this.#tanpura = createTanpura(Tone, base, [sa, pa]).connect(this.#ensureMaster(Tone));\n this.#tanpuraKey = key;\n }\n const players = this.#tanpura;\n players.volume.value = -14;\n\n const pattern = [pa, sa, sa, sa];\n // The drone keeps the লয়'s pulse too — one pluck every two matra.\n segments.forEach((seg, k) => {\n const from = k === 0 ? 0 : seg.beat * spb + shift;\n const to = k === segments.length - 1 ? Infinity : seg.endBeat * spb + shift;\n const every = (spb * 2) / seg.scale;\n this.#scheduleIds.push(\n transport.scheduleRepeat(\n (time) => {\n const stem = pattern[Math.round((transport.getSecondsAtTime(time) - from) / every) % pattern.length]!;\n if (players.has(stem)) players.player(stem).start(time);\n },\n every,\n from,\n to === Infinity ? undefined : to - from,\n ),\n );\n });\n }\n\n #tonicSemitone(): number {\n return parseTonic(this.#opts.tonic ?? this.#doc?.meta.tonic);\n }\n}\n","/**\n * Offline audio export — render a swaralipi doc to a downloadable WAV or MP3\n * **entirely in the browser** (no server): `Tone.Offline` renders the same\n * melody / tabla / tanpura arrangement the live player builds into an\n * OfflineAudioContext (faster than real time), then a pure encoder writes the\n * PCM out.\n *\n * Like the player, Tone is **dynamically imported** (so importing this module\n * in Node/SSR never touches `AudioContext`) and the MP3 path dynamically\n * imports lamejs (an *optional* peer dep — WAV needs no dependency at all).\n * The actual render needs a browser (Node has no OfflineAudioContext); the two\n * encoders below are pure and unit-testable on their own.\n *\n * ponytail: the melody/rhythm/tanpura scheduling mirrors player.ts `#arrange`\n * (minus highlights / caching / fades) — keep the two in sync.\n */\nimport type { GrainPlayer, Player } from 'tone';\nimport type { Swaralipi, Taal } from '../spec/index.js';\nimport { TAALS, type TaalId } from '../spec/taals.js';\nimport type { LaySpeeds } from '../spec/lay.js';\nimport { midiToSampleName, parseTonic } from './pitch.js';\nimport { buildSchedule, glideTargets, graceTouches, type Schedule, type TempoSegment } from './schedule.js';\nimport { alignLyrics, lyricCues, type Excerpt } from './lyrics.js';\nimport type { RhythmMode } from './player.js';\nimport {\n DEFAULT_SOUNDS_BASE,\n INSTRUMENTS,\n SAMPLED_TAALS,\n TABLA_GRAIN_OVERLAP_SEC,\n TABLA_GRAIN_SEC,\n TANPURA_PCS,\n createBuffers,\n createDrumKit,\n createMetronome,\n createSampler,\n createTanpura,\n drumPattern,\n nearestTablaBpm,\n normalizeBase,\n quantizeLoopEnd,\n tablaBpms,\n triggerGlide,\n tablaShiftSemitones,\n tablaUrl,\n type InstrumentDef,\n type InstrumentId,\n type ToneModule,\n} from './instruments.js';\n\nexport type AudioFormat = 'wav' | 'mp3';\n\n/** Seconds the outgoing tabla loop decays under the incoming one at a লয়\n * change (mirrors the player's LAY_TAIL_SEC). */\nconst LAY_TAIL_SEC = 0.12;\n\nexport interface AudioExportOptions {\n /** Play only the notes singing these stretches of the text (see alignLyrics). */\n excerpt?: Excerpt;\n /** The song's words: when given, the result carries their `cues` (an LRC's timing). */\n lyrics?: string;\n /** Samples host (santoor/tabla/tanpura/metronome). Default the project CDN. */\n soundsBaseUrl?: string;\n /** Self-host the grand piano (see the player's `pianoBaseUrl`). */\n pianoBaseUrl?: string;\n /** Extra melody instruments, keyed by id (see the player's option). */\n customInstruments?: Record<string, InstrumentDef>;\n /** Tonic (Sa). Accepts `C`, `C#`, `cs`… Default: doc tonic, else `C`. */\n tonic?: string;\n /** Tempo in matra/min — the **দ্রুত** (fast) tempo; লয় marks scale down from\n * it. Default: `meta.bpm`, else 90. Snapped to the tabla grid when a sampled\n * tabla actually plays. */\n bpm?: number;\n /** Override the লয় tempo factors (see LAY_SPEEDS / meta.laySpeeds). */\n laySpeeds?: LaySpeeds;\n /** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */\n baseOctave?: number;\n /** Melody instrument id. Default `piano`. */\n instrument?: InstrumentId;\n /** Include the notation (melody) voice. Default true. */\n melody?: boolean;\n /** Rhythm accompaniment: `tabla` (→ metronome for unsampled taals), `drums`\n * (Western drumset following sam/tali/khaali), `metronome`, or `none`.\n * Default `none` — the base export is notation only. */\n rhythm?: RhythmMode;\n /** Taal for the rhythm: an explicit id, or `auto` (from `meta.taal`). Default\n * `auto`. Only used when `rhythm` isn't `none`. */\n taal?: TaalId | 'auto';\n /** Rhythm first for a song that opens on a pickup, as the player's\n * `countIn`. Default false: the melody starts at once and the rhythm comes\n * in on the সম. */\n countIn?: boolean;\n /** Include the tanpura drone. Default false. */\n tanpura?: boolean;\n /** Sing the song's form (repeats, returns to the asthayi), as the player\n * does. Default true; false keeps the written order. */\n repeats?: boolean;\n /** Output format. Default `wav` (lossless, zero-dependency). `mp3` needs the\n * optional peer dep `@breezystack/lamejs`. */\n format?: AudioFormat;\n /** MP3 bitrate in kbps. Default 192. */\n mp3Kbps?: number;\n /** Output channels. Default 1 (the content is monophonic and centred, so mono\n * halves the file with no audible loss); set 2 for stereo. */\n channels?: 1 | 2;\n /** Sample rate. Default 44100. */\n sampleRate?: number;\n /** Fade the last N seconds so a looped tabla/tanpura doesn't hard-cut at the\n * render boundary. Default 0.4. */\n fadeOutSec?: number;\n}\n\nexport interface AudioExportResult {\n /** The encoded audio, ready to download or upload. */\n blob: Blob;\n /** Suggested `<title>.<ext>` download filename. */\n filename: string;\n mimeType: string;\n /** Rendered length in seconds. */\n durationSec: number;\n /** Each sung line and its words, in seconds on this file's timeline (given `lyrics`). */\n cues?: LyricCue[];\n}\n\nexport interface LyricCue {\n sec: number;\n words: { sec: number; text: string }[];\n}\n\n/** MIDI span (incl. কণ/রেশ graces) of a schedule, for sample subsetting. */\nfunction midiRange(schedule: Schedule): { lo: number; hi: number } | undefined {\n let lo = Infinity;\n let hi = -Infinity;\n for (const ev of schedule.events) {\n for (const m of [ev.midi, ...ev.kan, ...ev.resh]) {\n if (m !== null) {\n if (m < lo) lo = m;\n if (m > hi) hi = m;\n }\n }\n }\n return lo <= hi ? { lo, hi } : undefined;\n}\n\n/** Seconds of the song turned into nodes ahead of the renderer (see renderOffline). */\nconst AHEAD_SEC = 2;\n\n/**\n * Tone.Offline, made quick. Tone runs its clock over the whole song before the first sample, so\n * every note already exists as a pending node — and Chrome and WebKit process every pending node\n * for every 128-frame block: 240 s of 3000 notes took 152 s (Chrome) and 89 s (WebKit), against\n * 1.6 s and 1.2 s with each note made just ahead of the renderer. So the clock runs a chunk at a\n * time from the render's own suspend points. Firefox has no OfflineAudioContext.suspend() (157),\n * but renders the whole graph at once ~12x faster, so it gets the whole clock up front. Neither\n * path yields with setTimeout, which a background tab throttles to once a second.\n */\nasync function renderOffline(\n Tone: ToneModule,\n build: (context: InstanceType<ToneModule['OfflineContext']>) => Promise<void>,\n durationSec: number,\n channels: number,\n sampleRate: number,\n): Promise<AudioBuffer> {\n // Chunked needs a native context — Tone's wrapper (standardized-audio-context) has no\n // suspend() — and Tone needs the listener's AudioParams, which Firefox lacks.\n const chunked = 'suspend' in OfflineAudioContext.prototype && 'positionX' in AudioListener.prototype;\n const context = chunked\n ? new Tone.OfflineContext(new OfflineAudioContext(channels, Math.ceil(durationSec * sampleRate), sampleRate))\n : new Tone.OfflineContext(channels, durationSec, sampleRate);\n const raw = context.rawContext as unknown as OfflineAudioContext;\n const original = Tone.getContext();\n Tone.setContext(context);\n try {\n await build(context);\n } finally {\n Tone.setContext(original);\n }\n // Tone's own clock loop (OfflineContext#_renderClock), run only as far as `until`.\n const clock = context as unknown as { _currentTime: number; emit(event: 'tick'): void };\n const run = (until: number) => {\n while (clock._currentTime <= Math.min(until, durationSec)) {\n clock.emit('tick');\n clock._currentTime += 128 / sampleRate;\n }\n };\n if (chunked) {\n run(2 * AHEAD_SEC);\n for (let t = AHEAD_SEC; t < durationSec; t += AHEAD_SEC) {\n void raw.suspend(t).then(() => {\n run(t + 2 * AHEAD_SEC);\n void raw.resume();\n });\n }\n } else {\n run(Infinity);\n }\n return raw.startRendering();\n}\n\n/** Resolve the melody instrument def (mirrors the player's #resolveDef): a\n * custom override, the piano self-host shortcut, a CDN fallback for a local\n * instrument with no host, else the requested built-in. */\nfunction pickDef(id: string, o: AudioExportOptions): InstrumentDef {\n const def = o.customInstruments?.[id] ?? INSTRUMENTS[id];\n if (def === undefined) return INSTRUMENTS.harmonium!; // unknown id → CDN fallback\n if (id === 'piano' && o.pianoBaseUrl) return { ...def, baseUrl: normalizeBase(o.pianoBaseUrl) };\n if (def.local === true && !o.soundsBaseUrl) return INSTRUMENTS.harmonium!; // local needs a host\n return def;\n}\n\n/** The active taal id (explicit override, else the doc's opening one — a\n * তালফেরতা doc may carry it on its first row), or undefined for an\n * unknown/absent taal (→ metronome falls back to a 4-beat cycle). */\nfunction resolveTaal(doc: Swaralipi, taal: AudioExportOptions['taal']): TaalId | undefined {\n const id = taal !== undefined && taal !== 'auto' ? taal : (doc.parts[0]?.rows[0]?.taal || doc.meta.taal)?.id;\n return id !== undefined && id in TAALS ? (id as TaalId) : undefined;\n}\n\n/** Strip filesystem-hostile characters (keeps Bengali/Unicode letters). */\nfunction safeName(title: string | undefined): string {\n return (title ?? '').replace(/[\\\\/:*?\"<>|]+/g, '').trim() || 'swaralipi';\n}\n\n/**\n * Render a swaralipi doc to an audio Blob in the browser. Runs in an\n * OfflineAudioContext — no user gesture and no server needed. Throws in an\n * environment without Web Audio (Node/SSR) or, for `format: 'mp3'`, when the\n * optional `@breezystack/lamejs` peer dependency is not installed.\n */\nexport async function exportAudio(\n doc: Swaralipi,\n options: AudioExportOptions = {},\n): Promise<AudioExportResult> {\n const Tone: ToneModule = await import('tone');\n\n const base = options.soundsBaseUrl ?? DEFAULT_SOUNDS_BASE;\n const format = options.format ?? 'wav';\n const channels = options.channels ?? 1;\n const sampleRate = options.sampleRate ?? 44100;\n const fadeOutSec = options.fadeOutSec ?? 0.4;\n const rhythm: RhythmMode = options.rhythm ?? 'none';\n const withMelody = options.melody ?? true;\n const withTanpura = options.tanpura ?? false;\n\n const schedule = buildSchedule(doc, {\n tonic: options.tonic,\n baseOctave: options.baseOctave,\n laySpeeds: options.laySpeeds,\n repeats: options.repeats ?? true,\n excerpt: options.excerpt,\n });\n const range = midiRange(schedule);\n\n const taalId = resolveTaal(doc, options.taal);\n // An explicit taal is pinned across the whole song; 'auto' follows each\n // segment's own (তালফেরতা).\n const pinned: Taal | undefined =\n options.taal !== undefined && options.taal !== 'auto' && taalId !== undefined ? TAALS[taalId] : undefined;\n const usesTabla = rhythm === 'tabla' && taalId !== undefined && SAMPLED_TAALS.has(taalId) && !!base;\n\n const reqBpm = options.bpm ?? doc.meta.bpm ?? 90;\n const bpm = usesTabla && taalId ? nearestTablaBpm(reqBpm, tablaBpms(taalId)) : reqBpm;\n const spb = 60 / bpm;\n\n const id = options.instrument ?? 'piano';\n const def = pickDef(id, options);\n // A pickup waits for a count-in, or goes first with the rhythm coming in on\n // the সম (mirrors the player). The count-in lengthens the render.\n const countIn = options.countIn ?? false;\n const shift = countIn && rhythm !== 'none' ? schedule.pickupBeats * spb : 0;\n const entry = countIn ? 0 : schedule.samBeat * spb;\n const durationSec = Math.max(schedule.totalBeats * spb + shift + (def.release ?? 1) + fadeOutSec + 0.5, 0.5);\n\n const rendered = await renderOffline(\n Tone,\n async ({ transport }) => {\n transport.bpm.value = bpm;\n const master = new Tone.Gain(1).toDestination();\n\n // --- melody (the notation, sounded) ---\n if (withMelody) {\n const sampler = createSampler(Tone, def, base, range).connect(master);\n // মীড় glide voice — same samples, started once and pitch-automated\n // (mirrors the player; only built when the song actually glides).\n const glide = schedule.events.some((ev) => ev.glide === true)\n ? createBuffers(Tone, def, base, range)\n : undefined;\n schedule.events.forEach((ev, i) => {\n if (ev.glide === true) return;\n for (const g of graceTouches(ev)) {\n const name = midiToSampleName(g.midi);\n transport.scheduleOnce((t) => sampler.triggerAttackRelease(name, spb * 0.4, t), Math.max(g.beat * spb + shift, 0));\n }\n if (ev.midi === null) return;\n const at = ev.beat * spb + shift;\n const dur = Math.max(ev.durationBeats * spb, 0.05);\n const targets = glide !== undefined ? glideTargets(schedule.events, i) : [];\n if (targets.length > 0 && glide !== undefined) {\n const last = targets[targets.length - 1]!;\n const legs = [\n { midi: ev.midi, at: 0 },\n ...targets.map((t) => ({ midi: t.midi!, at: (t.beat - ev.beat) * spb })),\n ];\n const end = (last.beat + last.durationBeats - ev.beat) * spb;\n transport.scheduleOnce((t) => {\n triggerGlide(\n Tone,\n glide.buffers,\n glide.urls,\n master,\n legs.map((l) => ({ midi: l.midi, at: t + l.at })),\n t + end,\n def.release ?? 1,\n );\n }, at);\n } else {\n const name = midiToSampleName(ev.midi);\n transport.scheduleOnce((t) => sampler.triggerAttackRelease(name, dur, t), at);\n }\n });\n }\n\n // --- rhythm (looped tabla, drumset, or a metronome click) ---\n // One pass per লয় / তাল segment, exactly like the player's #buildRhythm:\n // the tabla is rebuilt at each segment's own tempo and taal (its own\n // recorded file when one exists, else the nearest time-stretched by\n // GrainPlayer), and a মুক্তছন্দ segment rests.\n const tablas: { loop: Player | GrainPlayer; fileSpb: number }[] = [];\n if (rhythm !== 'none' && base) {\n const drums = rhythm === 'drums' ? createDrumKit(Tone).connect(master) : undefined;\n let metro: Player | undefined;\n const semis = tablaShiftSemitones(parseTonic(options.tonic ?? doc.meta.tonic));\n\n schedule.tempo.forEach((seg: TempoSegment, i) => {\n const own = pinned ?? seg.taal;\n if (own === null) return;\n const segId = own !== undefined && own.id in TAALS ? (own.id as TaalId) : undefined;\n const from = Math.max(i === 0 ? 0 : seg.beat * spb + shift, entry);\n const to = i === schedule.tempo.length - 1 ? Infinity : seg.endBeat * spb + shift;\n if (from >= to) return;\n const beatSec = spb / seg.scale;\n const span = to === Infinity ? undefined : to - from;\n\n if (rhythm === 'tabla' && segId !== undefined && SAMPLED_TAALS.has(segId)) {\n const segBpm = 60 / beatSec;\n const fileBpm = nearestTablaBpm(segBpm, tablaBpms(segId));\n const rate = segBpm / fileBpm;\n const url = tablaUrl(base, segId, fileBpm, pinned === undefined ? own?.variation : undefined);\n const loop = (rate === 1 && semis === 0\n ? new Tone.Player({ url, loop: true })\n : new Tone.GrainPlayer({\n url,\n loop: true,\n playbackRate: rate,\n detune: semis * 100,\n grainSize: TABLA_GRAIN_SEC,\n overlap: TABLA_GRAIN_OVERLAP_SEC,\n })\n ).connect(master);\n loop.sync().start(from);\n if (span !== undefined) {\n transport.scheduleOnce((t) => {\n loop.volume.setValueAtTime(0, t);\n loop.volume.linearRampToValueAtTime(-40, t + LAY_TAIL_SEC);\n }, to);\n loop.stop(to + LAY_TAIL_SEC);\n }\n tablas.push({ loop, fileSpb: 60 / fileBpm });\n } else if (drums !== undefined) {\n const pattern = drumPattern(segId !== undefined ? TAALS[segId] : (own ?? { numBeats: 4, sam: 0 }));\n let beat = 0;\n transport.scheduleRepeat(\n (time) => {\n const voice = pattern[beat % pattern.length]!;\n if (drums.has(voice)) drums.player(voice).start(time);\n beat += 1;\n },\n beatSec,\n from,\n span,\n );\n } else {\n const click = (metro ??= createMetronome(Tone, base).connect(master));\n const cycle = own?.numBeats ?? 4;\n let beat = 0;\n transport.scheduleRepeat(\n (time) => {\n click.volume.setValueAtTime(beat % cycle === 0 ? 0 : -8, time);\n click.start(time);\n beat += 1;\n },\n beatSec,\n from,\n span,\n );\n }\n });\n }\n\n // --- tanpura drone (Pa–Sa–Sa–Sa, one pluck every two beats) ---\n if (withTanpura && base) {\n const tonicPc = ((parseTonic(options.tonic ?? doc.meta.tonic) % 12) + 12) % 12;\n const sa = TANPURA_PCS[tonicPc]!;\n const pa = TANPURA_PCS[(tonicPc + 7) % 12]!;\n const players = createTanpura(Tone, base, [sa, pa]).connect(master);\n players.volume.value = -14;\n const pattern = [pa, sa, sa, sa];\n schedule.tempo.forEach((seg: TempoSegment, k) => {\n const from = k === 0 ? 0 : seg.beat * spb + shift;\n const to = k === schedule.tempo.length - 1 ? Infinity : seg.endBeat * spb + shift;\n let i = 0;\n transport.scheduleRepeat(\n (time) => {\n const stem = pattern[i % pattern.length]!;\n if (players.has(stem)) players.player(stem).start(time);\n i += 1;\n },\n (spb * 2) / seg.scale,\n from,\n to === Infinity ? undefined : to - from,\n );\n });\n }\n\n // Buffers must be loaded before the (one-shot) render, or they arrive too\n // late to be heard — the async callback is awaited, so this is the fix.\n await Tone.loaded();\n // Snap a mistrimmed tabla loop to whole beats of ITS OWN recorded tempo\n // now its length is known (loop points are buffer time, not song time).\n for (const { loop, fileSpb } of tablas) {\n if (loop.buffer?.loaded) loop.loopEnd = quantizeLoopEnd(loop.buffer.duration, fileSpb);\n }\n\n // Soften the tail so looped accompaniment doesn't click off at the edge.\n if (fadeOutSec > 0) {\n master.gain.setValueAtTime(1, Math.max(durationSec - fadeOutSec, 0));\n master.gain.linearRampToValueAtTime(0, durationSec);\n }\n transport.start(0);\n },\n durationSec,\n channels,\n sampleRate,\n );\n\n const chans: Float32Array[] = [];\n for (let c = 0; c < rendered.numberOfChannels; c++) chans.push(rendered.getChannelData(c));\n\n const bytes =\n format === 'mp3'\n ? await encodeMp3(chans, rendered.sampleRate, options.mp3Kbps)\n : encodeWav(chans, rendered.sampleRate);\n const mimeType = format === 'mp3' ? 'audio/mpeg' : 'audio/wav';\n const cues = options.lyrics === undefined\n ? undefined\n : lyricCues(schedule.events, alignLyrics(doc, options.lyrics), options.lyrics).map((cue) => ({\n sec: cue.beat * spb + shift,\n words: cue.words.map((word) => ({ sec: word.beat * spb + shift, text: word.text })),\n }));\n return {\n blob: new Blob([bytes as BlobPart], { type: mimeType }),\n filename: `${safeName(doc.meta.title)}.${format}`,\n mimeType,\n durationSec: rendered.duration,\n ...(cues === undefined ? {} : { cues }),\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Pure encoders (browser-free, unit-testable) */\n/* ------------------------------------------------------------------ */\n\n/** Clamp a float sample to a 16-bit signed integer. */\nfunction toInt16(f: number): number {\n const s = f < -1 ? -1 : f > 1 ? 1 : f;\n return s < 0 ? s * 0x8000 : s * 0x7fff;\n}\n\n/**\n * Encode planar float channels to a 16-bit PCM WAV (RIFF). Pure — no Web Audio\n * — so it runs (and tests) in Node. 16-bit PCM is lossless CD quality and plays\n * everywhere; float/24-bit skipped (add if mastering-grade output is needed).\n */\nexport function encodeWav(channels: Float32Array[], sampleRate: number): Uint8Array {\n const numCh = channels.length;\n const frames = channels[0]?.length ?? 0;\n const bytesPerSample = 2;\n const blockAlign = numCh * bytesPerSample;\n const dataSize = frames * blockAlign;\n const buf = new ArrayBuffer(44 + dataSize);\n const view = new DataView(buf);\n const str = (off: number, s: string) => {\n for (let i = 0; i < s.length; i++) view.setUint8(off + i, s.charCodeAt(i));\n };\n\n str(0, 'RIFF');\n view.setUint32(4, 36 + dataSize, true);\n str(8, 'WAVE');\n str(12, 'fmt ');\n view.setUint32(16, 16, true); // PCM fmt chunk size\n view.setUint16(20, 1, true); // format = PCM\n view.setUint16(22, numCh, true);\n view.setUint32(24, sampleRate, true);\n view.setUint32(28, sampleRate * blockAlign, true); // byte rate\n view.setUint16(32, blockAlign, true);\n view.setUint16(34, bytesPerSample * 8, true); // bits per sample\n str(36, 'data');\n view.setUint32(40, dataSize, true);\n\n let off = 44;\n for (let f = 0; f < frames; f++) {\n for (let c = 0; c < numCh; c++) {\n view.setInt16(off, toInt16(channels[c]![f]!), true);\n off += 2;\n }\n }\n return new Uint8Array(buf);\n}\n\n/** Convert a float channel to the Int16 samples lamejs expects. */\nfunction floatToInt16(f: Float32Array): Int16Array {\n const out = new Int16Array(f.length);\n for (let i = 0; i < f.length; i++) out[i] = toInt16(f[i]!);\n return out;\n}\n\nfunction concatBytes(chunks: Uint8Array[]): Uint8Array {\n const total = chunks.reduce((n, c) => n + c.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const c of chunks) {\n out.set(c, off);\n off += c.length;\n }\n return out;\n}\n\n/** Load the optional lamejs encoder, tolerating named/default export shapes. */\nasync function loadLame(): Promise<{ new (channels: number, sampleRate: number, kbps: number): Mp3EncoderLike }> {\n try {\n const mod = (await import('@breezystack/lamejs')) as unknown as {\n Mp3Encoder?: new (c: number, s: number, k: number) => Mp3EncoderLike;\n default?: { Mp3Encoder: new (c: number, s: number, k: number) => Mp3EncoderLike };\n };\n const Mp3Encoder = mod.Mp3Encoder ?? mod.default?.Mp3Encoder;\n if (!Mp3Encoder) throw new Error('no Mp3Encoder export');\n return Mp3Encoder;\n } catch {\n throw new Error(\n 'MP3 export needs the optional peer dependency \"@breezystack/lamejs\" — ' +\n 'install it, or export as WAV (format: \"wav\").',\n );\n }\n}\n\ninterface Mp3EncoderLike {\n encodeBuffer(left: Int16Array, right?: Int16Array): Int8Array;\n flush(): Int8Array;\n}\n\n/**\n * A streaming MP3 encoder: feed 16-bit PCM in any number of pieces, get one MP3 — one encoder\n * delay, so a track joined from several renders keeps its timing. lamejs is **dynamically\n * imported** and an *optional* peer dependency (LGPL-3.0). Samples go in 1152-frame blocks (a\n * multiple of 576, lamejs' preferred size).\n */\nexport async function mp3Stream(\n sampleRate = 44100,\n kbps = 192,\n channels: 1 | 2 = 1,\n): Promise<{ push(left: Int16Array, right?: Int16Array): void; end(): Uint8Array[] }> {\n const Mp3Encoder = await loadLame();\n const enc = new Mp3Encoder(channels, sampleRate, kbps);\n const out: Uint8Array[] = [];\n const keep = (chunk: Int8Array) => {\n if (chunk.length > 0) out.push(new Uint8Array(chunk));\n };\n const block = 1152;\n return {\n push(left, right) {\n for (let i = 0; i < left.length; i += block) {\n const l = left.subarray(i, i + block);\n keep(right ? enc.encodeBuffer(l, right.subarray(i, i + block)) : enc.encodeBuffer(l));\n }\n },\n end() {\n keep(enc.flush());\n return out;\n },\n };\n}\n\n/** Encode planar float channels to MP3 via lamejs (see mp3Stream). WAV needs no dependency, so\n * only reach for this when a compressed file is wanted. */\nexport async function encodeMp3(\n channels: Float32Array[],\n sampleRate: number,\n kbps = 192,\n): Promise<Uint8Array> {\n const numCh = Math.min(channels.length, 2) as 1 | 2; // lamejs is mono or stereo\n const mp3 = await mp3Stream(sampleRate, kbps, numCh);\n mp3.push(floatToInt16(channels[0] ?? new Float32Array()), numCh > 1 ? floatToInt16(channels[1]!) : undefined);\n return concatBytes(mp3.end());\n}\n","/**\n * MIDI export — write a swaralipi doc to a downloadable Standard MIDI File.\n *\n * Unlike the audio export this needs **no Tone and no AudioContext**: MIDI is\n * just note events, and `buildSchedule` already gives us (midi, beat,\n * durationBeats) per note. So the whole thing is pure bytes — it runs (and\n * tests) in plain Node, and carries no dependency (the SMF format is trivial),\n * which keeps it clear of any redistribution/license question.\n *\n * Scope = the **melody voice**, plus — when `drums` is on — the Western-drumset\n * translation of the taal (the same `drumPattern` the player sequences) written\n * as a **separate GM channel-10 track**. Tabla is prerecorded audio loops with\n * no per-stroke note data, so there's nothing to turn into MIDI notes; tanpura\n * is a fixed background drone. A `.mid` here is the notation line (+ optional\n * drums) — the user opens it in any DAW and assigns instruments.\n */\nimport type { Swaralipi } from '../spec/index.js';\nimport { TAALS } from '../spec/taals.js';\nimport type { LaySpeeds } from '../spec/lay.js';\nimport type { Excerpt } from './lyrics.js';\nimport { GRACE_STEP, buildSchedule, glideTargets, graceTouches, type Schedule, type TempoSegment } from './schedule.js';\nimport { MEEND_HOLD, drumPattern, type DrumVoice } from './instruments.js';\nimport { sCurve } from './pitch.js';\n\n/** Pulses per quarter note. One matra (beat) == one quarter note. */\nconst PPQ = 480;\n\nexport interface MidiExportOptions {\n /** Play only the notes singing these stretches of the text (see alignLyrics). */\n excerpt?: Excerpt;\n /** Tonic (Sa). Accepts `C`, `C#`, `cs`… Default: doc tonic, else `C`. */\n tonic?: string;\n /** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */\n baseOctave?: number;\n /** Tempo in matra/min written as the file's tempo — the **দ্রুত** tempo;\n * লয় marks come out as longer note values against it, not as tempo changes.\n * Default `meta.bpm`, else 90. */\n bpm?: number;\n /** Override the লয় tempo factors (see LAY_SPEEDS / meta.laySpeeds). */\n laySpeeds?: LaySpeeds;\n /** Track name meta-event. Default the song title. */\n name?: string;\n /** Also export the taal's drumset pattern as a separate GM channel-10 track. */\n drums?: boolean;\n /** With `drums`, a song that opens on a pickup starts with the drums' count-in\n * and the melody after it, as the player's `countIn`. Default false: the\n * melody starts at once and the drums come in on the সম. */\n countIn?: boolean;\n /** Sing the song's form (repeats, returns to the asthayi), as the player\n * does. Default true; false keeps the written order. */\n repeats?: boolean;\n}\n\nexport interface MidiExportResult {\n blob: Blob;\n /** Suggested `<title>.mid` filename. */\n filename: string;\n mimeType: string;\n}\n\n/** Variable-length quantity (7 bits/byte, high bit = continue). */\nfunction vlq(n: number): number[] {\n const out = [n & 0x7f];\n n >>>= 7;\n while (n > 0) {\n out.unshift((n & 0x7f) | 0x80);\n n >>>= 7;\n }\n return out;\n}\n\n/** UTF-8 bytes of a string (Bengali titles survive; most DAWs read UTF-8). */\nfunction utf8(s: string): number[] {\n return [...new TextEncoder().encode(s)];\n}\n\nfunction u32be(n: number): number[] {\n return [(n >>> 24) & 0xff, (n >>> 16) & 0xff, (n >>> 8) & 0xff, n & 0xff];\n}\n\ninterface RawEvent {\n tick: number;\n on: boolean;\n note: number;\n vel: number;\n ch: number;\n /** Status byte override; `note`/`vel` then carry the two data bytes. Used\n * for the pitch-bend and RPN messages a মীড় needs. */\n status?: number;\n meta?: number[];\n}\n\n/**\n * Pitch-bend range, in semitones, declared once via RPN 0. The GM default is\n * only ±2, but corpus মীড়s reach 7 semitones and a basic meend \"can range from\n * a simple span of 2 notes to a whole octave\" (ITC SRA), so the file asks for\n * ±12. A DAW that ignores the RPN will play the glides too wide.\n */\nconst BEND_RANGE = 12;\n\n/** Bend steps written per মীড় leg — the S-curve sampled fine enough to read\n * as a continuous slide in any sequencer. */\nconst BEND_STEPS = 16;\n\n/** 14-bit pitch-bend message for a signed semitone offset (0 = centre). */\nfunction bendEvent(tick: number, semitones: number): RawEvent {\n const raw = Math.round(8192 + (semitones / BEND_RANGE) * 8192);\n const value = Math.min(Math.max(raw, 0), 16383);\n return { tick, on: false, status: 0xe0, note: value & 0x7f, vel: (value >> 7) & 0x7f, ch: 0 };\n}\n\n/** RPN 0 = pitch-bend sensitivity, so the ±12 semitone glides land right. */\nfunction bendRangeSetup(): RawEvent[] {\n const cc = (num: number, val: number): RawEvent => ({ tick: 0, on: false, status: 0xb0, note: num, vel: val, ch: 0 });\n return [cc(101, 0), cc(100, 0), cc(6, BEND_RANGE), cc(38, 0), cc(101, 127), cc(100, 127)];\n}\n\n/** General MIDI channel-10 (index 9) percussion note per drumset voice. */\nconst DRUM_NOTE: Record<DrumVoice, number> = {\n kick: 36,\n snare: 38,\n hihat: 42, // closed hi-hat\n tom1: 48,\n tom2: 45,\n tom3: 41,\n};\n\n/** Serialise sorted raw events into an MTrk chunk (bytes, incl. header). */\nfunction trackChunk(raw: RawEvent[], head: number[]): number[] {\n // Time order; at equal ticks: release, then any bend/CC, then attack — so a\n // repeated pitch never hangs and a bend reset can't touch the next note.\n const rank = (e: RawEvent) => (e.status !== undefined ? 1 : e.on ? 2 : 0);\n raw.sort((a, b) => a.tick - b.tick || rank(a) - rank(b));\n const track = [...head];\n let last = 0;\n for (const e of raw) {\n if (e.meta) {\n track.push(...vlq(e.tick - last), ...e.meta);\n last = e.tick;\n continue;\n }\n const status = e.status !== undefined ? e.status | (e.ch & 0x0f) : (e.on ? 0x90 : 0x80) | (e.ch & 0x0f);\n track.push(...vlq(e.tick - last), status, e.note & 0x7f, e.vel & 0x7f);\n last = e.tick;\n }\n track.push(...vlq(0), 0xff, 0x2f, 0x00); // end of track\n return [0x4d, 0x54, 0x72, 0x6b, ...u32be(track.length), ...track];\n}\n\n/**\n * Encode a schedule to a Standard MIDI File. Melody rides channel 0; when\n * `drums` is given, its per-matra voices ride a second GM channel-10 track\n * (the file becomes format 1). `drums` is one pattern for the whole song, or a\n * function picking each লয় / তাল segment's own (তালফেরতা; `undefined` = rest).\n * Pure — no Tone, no browser — directly testable.\n */\nfunction melodyEvents(schedule: Schedule, offset = 0): RawEvent[] {\n const melody: RawEvent[] = [];\n const hasGlide = schedule.events.some((ev) => ev.glide === true);\n if (hasGlide) melody.push(...bendRangeSetup());\n schedule.events.forEach((ev, i) => {\n // A মীড় target is not struck: it is bent into from the note before it.\n if (ev.glide === true) return;\n // Each grace lasts one step, so it never overlaps the next grace or a কণ's attack.\n for (const g of graceTouches(ev)) {\n const on = Math.max(Math.round(g.beat * PPQ) + offset, 0);\n melody.push({ tick: on, on: true, note: g.midi, vel: 70, ch: 0 });\n melody.push({ tick: Math.max(on + 1, Math.round((g.beat + GRACE_STEP) * PPQ) + offset), on: false, note: g.midi, vel: 0, ch: 0 });\n }\n if (ev.midi === null) return;\n const start = Math.round(ev.beat * PPQ) + offset;\n const targets = glideTargets(schedule.events, i);\n const last = targets[targets.length - 1] ?? ev;\n const end = Math.max(Math.round((last.beat + last.durationBeats) * PPQ) + offset, start + 1);\n melody.push({ tick: start, on: true, note: ev.midi, vel: 100, ch: 0 });\n melody.push({ tick: end, on: false, note: ev.midi, vel: 0, ch: 0 });\n\n // One held note + a bent S-curve per leg: hold the source svara for\n // MEEND_HOLD of the gap, then roll into the target, arriving on its matra.\n let from = ev;\n for (const to of targets) {\n const glideStart = from.beat + (to.beat - from.beat) * MEEND_HOLD;\n for (let n = 0; n <= BEND_STEPS; n++) {\n const u = n / BEND_STEPS;\n const beat = glideStart + (to.beat - glideStart) * u;\n const semis = from.midi! - ev.midi + (to.midi! - from.midi!) * sCurve(u);\n melody.push(bendEvent(Math.round(beat * PPQ) + offset, semis));\n }\n from = to;\n }\n if (targets.length > 0) melody.push(bendEvent(end, 0)); // centre before the next note\n });\n return melody;\n}\n\n/** Beats the melody waits for a drum count-in (see MidiExportOptions.countIn). */\nconst leadIn = (schedule: Schedule, countIn: boolean | undefined): number => (countIn ? schedule.pickupBeats : 0);\n\nfunction drumEvents(\n schedule: Schedule,\n drums: DrumVoice[] | ((seg: TempoSegment) => DrumVoice[] | undefined),\n offset = 0,\n countIn = false,\n): RawEvent[] {\n const drum: RawEvent[] = [];\n const shift = leadIn(schedule, countIn);\n // A pickup goes first unless the drums count it in: then they come in on the সম.\n const entry = countIn ? 0 : schedule.samBeat;\n schedule.tempo.forEach((seg, i) => {\n const pattern = typeof drums === 'function' ? drums(seg) : drums;\n if (!pattern?.length) return;\n // One stroke per written matra, spaced by the segment's লয়; each segment\n // restarts its pattern on the সম it begins with.\n const from = Math.max(i === 0 ? 0 : seg.beat + shift, entry);\n const end = (i === schedule.tempo.length - 1 ? Math.ceil(schedule.totalBeats) : seg.endBeat) + shift;\n for (let k = 0; from + k / seg.scale < end - 1e-6; k++) {\n const note = DRUM_NOTE[pattern[k % pattern.length]!];\n const t = Math.round((from + k / seg.scale) * PPQ) + offset;\n drum.push({ tick: t, on: true, note, vel: 100, ch: 9 });\n drum.push({ tick: t + Math.round(PPQ / 4), on: false, note, vel: 0, ch: 9 }); // one-shot: short gate\n }\n });\n return drum;\n}\n\nfunction midiFile(chunks: number[][]): Uint8Array {\n const format = chunks.length > 1 ? 1 : 0;\n const header = [0x4d, 0x54, 0x68, 0x64, ...u32be(6), 0x00, format, (chunks.length >> 8) & 0xff, chunks.length & 0xff, (PPQ >> 8) & 0xff, PPQ & 0xff];\n return new Uint8Array([...header, ...chunks.flat()]);\n}\n\nfunction meta(type: number, data: number[]): number[] {\n return [0xff, type, ...vlq(data.length), ...data];\n}\n\nexport function encodeMidi(\n schedule: Schedule,\n opts: {\n bpm: number;\n name?: string;\n drums?: DrumVoice[] | ((seg: TempoSegment) => DrumVoice[] | undefined);\n countIn?: boolean;\n },\n): Uint8Array {\n // Tempo lives on the first track alongside the name.\n const usPerBeat = Math.round(60_000_000 / opts.bpm);\n const head: number[] = [];\n if (opts.name) head.push(...vlq(0), 0xff, 0x03, ...vlq(utf8(opts.name).length), ...utf8(opts.name));\n head.push(...vlq(0), 0xff, 0x51, 0x03, (usPerBeat >> 16) & 0xff, (usPerBeat >> 8) & 0xff, usPerBeat & 0xff);\n\n const withDrums = typeof opts.drums === 'function' || (opts.drums !== undefined && opts.drums.length > 0);\n const lead = withDrums ? leadIn(schedule, opts.countIn) : 0;\n const chunks = [trackChunk(melodyEvents(schedule, Math.round(lead * PPQ)), head)];\n\n if (withDrums) {\n const drum = drumEvents(schedule, opts.drums!, 0, opts.countIn);\n chunks.push(trackChunk(drum, [...vlq(0), 0xff, 0x03, ...vlq(5), 0x44, 0x72, 0x75, 0x6d, 0x73])); // \"Drums\"\n }\n\n return midiFile(chunks);\n}\n\n/** The song as exported: its form sung (repeats), its লয় baked into the durations. */\nfunction exportSchedule(doc: Swaralipi, o: MidiExportOptions): Schedule {\n return buildSchedule(doc, { tonic: o.tonic, baseOctave: o.baseOctave, laySpeeds: o.laySpeeds, repeats: o.repeats ?? true, excerpt: o.excerpt });\n}\n\n/** Each segment drums its own taal (তালফেরতা); a মুক্তছন্দ segment rests. */\nfunction taalDrums(seg: TempoSegment): DrumVoice[] | undefined {\n if (seg.taal === null) return undefined;\n const id = seg.taal?.id;\n return drumPattern(id !== undefined && id in TAALS ? TAALS[id as keyof typeof TAALS] : { numBeats: 4, sam: 0 });\n}\n\n/** Strip filesystem-hostile characters (keeps Bengali/Unicode letters). */\nfunction safeName(title: string | undefined): string {\n return (title ?? '').replace(/[\\\\/:*?\"<>|]+/g, '').trim() || 'swaralipi';\n}\n\n/**\n * Export a swaralipi doc to a `.mid` Blob (melody voice only). No browser APIs\n * beyond `Blob` (present in Node 20+ too), so it works client-side or server-side.\n */\nexport function exportMidi(doc: Swaralipi, options: MidiExportOptions = {}): MidiExportResult {\n // লয় is baked into the durations: at one MIDI tempo, a বিলম্বিত passage is\n // the same notes written twice as long — which is what a DAW should show.\n const schedule = exportSchedule(doc, options);\n const bpm = options.bpm ?? doc.meta.bpm ?? 90;\n const bytes = encodeMidi(schedule, {\n bpm,\n name: options.name ?? doc.meta.title,\n drums: options.drums ? taalDrums : undefined,\n countIn: options.countIn,\n });\n return {\n blob: new Blob([bytes as BlobPart], { type: 'audio/midi' }),\n filename: `${safeName(doc.meta.title)}.mid`,\n mimeType: 'audio/midi',\n };\n}\n\n/** Several songs on one timeline (a whole dance-drama), back to back with two beats' rest:\n * each song opens with its own tempo and a marker naming it; drums share one channel-10 track. */\nexport function exportMidiSet(items: { doc: Swaralipi; options?: MidiExportOptions }[], name: string): MidiExportResult {\n const melody: RawEvent[] = [];\n const drum: RawEvent[] = [];\n let beat = 0;\n for (const { doc, options = {} } of items) {\n const schedule = exportSchedule(doc, options);\n const tick = beat * PPQ;\n const usPerBeat = Math.round(60_000_000 / (options.bpm ?? doc.meta.bpm ?? 90));\n const at = (bytes: number[]): RawEvent => ({ tick, on: false, note: 0, vel: 0, ch: 0, meta: bytes });\n melody.push(at(meta(0x51, [(usPerBeat >> 16) & 0xff, (usPerBeat >> 8) & 0xff, usPerBeat & 0xff])));\n const lead = options.drums ? leadIn(schedule, options.countIn) : 0;\n melody.push(at(meta(0x06, utf8(options.name ?? doc.meta.title ?? ''))), ...melodyEvents(schedule, tick + Math.round(lead * PPQ)));\n if (options.drums) drum.push(...drumEvents(schedule, taalDrums, tick, options.countIn));\n beat += Math.ceil(schedule.totalBeats + lead) + 2;\n }\n const chunks = [trackChunk(melody, [...vlq(0), ...meta(0x03, utf8(name))])];\n if (drum.length > 0) chunks.push(trackChunk(drum, [...vlq(0), ...meta(0x03, utf8('Drums'))]));\n const bytes = midiFile(chunks);\n return { blob: new Blob([bytes as BlobPart], { type: 'audio/midi' }), filename: `${safeName(name)}.mid`, mimeType: 'audio/midi' };\n}\n"]}
|