@xromdev/notation 0.0.0-stage → 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score.js","sourceRoot":"","sources":["../src/score.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A track as a SCORE: each pitched channel on a grand staff, the noise channel\n * on a percussion staff, and the dynamics its volumes imply.\n *\n * Built on `./notation`, so a bar here is spelled exactly the way a single\n * scrolling staff spells it — same bar line, same phase, same\n * note values. What this file adds is the part a page of music needs and a\n * single strip does not: which of two staves a note goes on, and what the\n * volume column says in the words a player reads.\n */\n\nimport {\n MEASURE_TICKS,\n TICKS_PER_QUARTER,\n barAt,\n barCountOf,\n barring,\n chooseClef,\n shiftNotes,\n staffItems,\n staffMeasures,\n voicePhase,\n type BarGrid,\n type OddBar,\n type StaffItem,\n type TickNote,\n} from './notation.js';\n\n/**\n * Middle C: in a beam group kept on the bass, the heads from here up still go\n * onto the treble and the beam crosses to them — see `crossStaffVoice`.\n */\nexport const GRAND_STAFF_SPLIT = 60;\n\nexport function splitGrandStaff<T extends { midi: number }>(\n notes: readonly T[],\n split = GRAND_STAFF_SPLIT\n): { treble: T[]; bass: T[] } {\n const treble: T[] = [];\n const bass: T[] = [];\n for (const note of notes) (note.midi >= split ? treble : bass).push(note);\n return { treble, bass };\n}\n\n/** A beam group that never goes below E3 — three ledger lines under the treble — is written on the treble. */\nexport const TREBLE_FLOOR = 52;\n\n/** Durations beamed together, one group per beat — `beamsFor`'s set. */\nconst BEAMED = new Set(['8', '16', '32', '64']);\n\n/**\n * A grand-staff part as ONE voice, each item saying which of the two staves it\n * stands on.\n *\n * Decided per BEAM GROUP — the beamed notes of one beat, or a note on its own —\n * because a beam is what a reader follows:\n *\n * - a group that never goes below E3 (`TREBLE_FLOOR`) is on the treble, E3\n * included. Ragnarok's canyon, pulse 1, bar 29, the third beat: A3 G3 C4 A3\n * E4 C4 G4 E4 — a reader wanted it all on the treble.\n * - a group that does go below E3 stays on the bass, E3s and all — bar 29's\n * second beat, E3 G3 C3 E3…, which \"would be ugly otherwise\". Only its heads\n * from middle C up cross to the treble, and the beam crosses with them — the\n * piano's cross-staff writing, drawn as one beam between the\n * staves with no rest on either side. Bar 30's lone G5 among B2s is that case.\n *\n * Every rule tried per BAR before this failed on a bar of this music: a bar\n * that starts low and climbs three octaves has a bass half and a treble half,\n * and the only choices a whole bar has are to tear its beams with rests or put\n * half of it on four ledger lines.\n *\n * A piece tied on from the head before it stays where that head stood; a rest\n * stands where the head before it in the bar did (else the first head after\n * it), and a bar with no heads at all is the treble's, so the bass shows its\n * own bar rest rather than a second one.\n */\nexport function crossStaffVoice(bars: readonly (readonly ScoreItem[])[]): ScoreItem[][] {\n let carried: 'treble' | 'bass' = 'treble';\n /*\n * A head whose beam runs on into the next bar (`crossBarRuns`) belongs to the group on the OTHER\n * side of the bar line, not to the beat it sits in — so it is written after that group has\n * chosen, and put on the same staff. Ragnarok's canyon, bar 25: the last E3 ends a beat of G4s\n * and went to the treble with them, while the D3 E3 it is beamed to are on the bass, and the\n * beam fell across the whole grand staff.\n */\n let hanging: ScoreItem[] | null = null;\n const written = bars.map((items) => {\n /*\n * The beat a head stands on, counted from ITS OWN bar line — the bar's\n * first item, since a bar is filled from its line. Counted with `%` off the\n * piece's clock instead, as this once was, it is right only while every bar\n * is the same length and the first starts on tick 0: Volkmire's Inferno\n * Race, barred from tick 6 with an opening bar of 19/32, had the two halves\n * of one arpeggio sorted into each other's beats, and the run came out torn\n * between the staves.\n */\n const barStart = items[0]?.start ?? 0;\n const groups = new Map<string, number[]>();\n items.forEach((item, index) => {\n if (item.midi === null) return;\n const key = BEAMED.has(item.duration)\n ? `beat${Math.floor((item.start - barStart) / TICKS_PER_QUARTER)}`\n : `note${index}`;\n groups.set(key, [...(groups.get(key) ?? []), index]);\n });\n\n const chosen: ('treble' | 'bass')[] = items.map(() => 'treble');\n for (const members of groups.values()) {\n const low = Math.min(...members.map((index) => items[index].midi as number));\n for (const index of members) {\n const midi = items[index].midi as number;\n chosen[index] = low >= TREBLE_FLOOR || midi >= GRAND_STAFF_SPLIT ? 'treble' : 'bass';\n }\n }\n\n let previous = carried;\n const heads = items.map((item, index) => {\n if (item.midi === null) return item;\n const staff = item.tieStop ? previous : chosen[index];\n previous = staff;\n return { ...item, staff };\n });\n carried = previous;\n\n const firstHead = heads.find((item) => item.midi !== null)?.staff ?? 'treble';\n let before: 'treble' | 'bass' | undefined;\n const bar = heads.map((item) => {\n if (item.midi !== null) {\n before = item.staff;\n return item;\n }\n return { ...item, staff: before ?? firstHead };\n });\n\n const reached = bar.find((item) => item.across === 'join');\n if (hanging && reached) {\n for (const item of hanging) item.staff = reached.staff;\n carried = reached.staff ?? carried;\n }\n hanging = bar.filter((item) => item.across === 'start');\n return bar;\n });\n return written;\n}\n\n/** The highest a part may reach and still be written on the bass staff alone: E4, two ledger lines up. */\nexport const BASS_ONLY_MAX = 64;\n/** The lowest a part may reach and still be written on the treble staff alone: G3, two ledger lines down. */\nexport const TREBLE_ONLY_MIN = 55;\n\n/**\n * The staves a part needs: one when every note it plays sits within two ledger\n * lines of a single staff, both otherwise.\n *\n * A grand staff whose other half is a whole track of rests is furniture: the\n * triangle carries the bass in every one of the twenty tracks, and in\n * Ragnarok's canyon it reaches D#4 at most — a ledger line and a half above the\n * bass staff. Where both single staves would do, the part's middle decides.\n */\nexport function partStaves(notes: readonly { midi: number }[]): ('treble' | 'bass')[] {\n if (notes.length === 0) return ['treble'];\n let low = Infinity;\n let high = -Infinity;\n for (const note of notes) {\n low = Math.min(low, note.midi);\n high = Math.max(high, note.midi);\n }\n const bass = high <= BASS_ONLY_MAX;\n const treble = low >= TREBLE_ONLY_MIN;\n if (bass && treble) return [chooseClef(notes)];\n if (bass) return ['bass'];\n if (treble) return ['treble'];\n return ['treble', 'bass'];\n}\n\nexport type Dynamic = 'pp' | 'p' | 'mp' | 'mf' | 'f' | 'ff';\nconst DYNAMICS: readonly Dynamic[] = ['pp', 'p', 'mp', 'mf', 'f', 'ff'];\n\n/**\n * The APU's 0..15 volume in six steps.\n *\n * A READING, not a fact: the nibble is linear in output level and a dynamic is\n * a word about loudness, so the steps are even in the nibble and nothing more\n * is claimed for them.\n */\nexport function dynamicOf(volume: number): Dynamic {\n const level = Math.max(0, Math.min(15, Math.round(volume)));\n return DYNAMICS[Math.min(DYNAMICS.length - 1, Math.floor((level * DYNAMICS.length) / 16))];\n}\n\n/** A change of level closer than this, in ticks, is folded into the mark before it. A quarter note. */\nexport const DYNAMIC_HOLD = 16;\n\n/** The words a mark can carry after its level: a figure's shape, or \"the same again\". */\nexport type DynamicWords = 'dim.' | 'cresc.' | 'sim.';\n\nexport interface DynamicMark {\n tick: number;\n dynamic: Dynamic;\n /**\n * How the figure goes from here: `dim.` and `cresc.` are a hairpin after the\n * level, `sim.` is the word alone — the level is the figure's own — with a\n * dashed line for as long as it holds.\n */\n words?: DynamicWords;\n /** With `words`: the tick of the last note the hairpin or the `sim.` covers. */\n until?: number; /**\n * A hairpin from a level the reader is already at: the hairpin alone, no\n * letter — ragnarok's 7 7 4 2, an mp going on from the mp before it.\n */\n bare?: boolean;\n}\n\n/** Onset to onset, notes closer than this can make one shaped figure. An eighth note. */\nexport const FIGURE_GAP = 8;\n\n/**\n * And no closer than this, a sixteenth. Faster is one note's envelope struck\n * again and again — Arctic Caverns' 8 4 2 1 in thirty-seconds on one pitch, an\n * echo — not a figure a player shapes.\n */\nexport const FIGURE_STEP = 4;\n\n/** A run of notes whose level only falls, or only rises: `[from, to]` are indices, inclusive. */\nexport interface ShapedFigure {\n from: number;\n to: number;\n words: 'dim.' | 'cresc.';\n}\n\n/**\n * Runs of at least three notes, each `FIGURE_STEP` to `FIGURE_GAP` after the one before, whose\n * level moves one way every step and by two or more in all — the 4 3 2 1 under\n * every beat of a fading figure. The six steps of `dynamicOf` cannot show that:\n * 4 and 3 are both p, and the hold folds the pp of 2 and 1 back into it.\n *\n * `notes` must be in order of start.\n */\nexport function shapedFigures(\n notes: readonly { start: number; volume: number }[],\n gap = FIGURE_GAP\n): ShapedFigure[] {\n const figures: ShapedFigure[] = [];\n let from = 0;\n while (from < notes.length - 2) {\n const step = Math.sign(notes[from + 1].volume - notes[from].volume);\n let to = from;\n while (\n step !== 0 &&\n to + 1 < notes.length &&\n notes[to + 1].start - notes[to].start <= gap &&\n notes[to + 1].start - notes[to].start >= FIGURE_STEP &&\n Math.sign(notes[to + 1].volume - notes[to].volume) === step\n ) {\n to++;\n }\n if (to - from >= 2 && Math.abs(notes[to].volume - notes[from].volume) >= 2) {\n figures.push({ from, to, words: step < 0 ? 'dim.' : 'cresc.' });\n from = to + 1;\n } else {\n from++;\n }\n }\n return figures;\n}\n\n/**\n * Two figures `sim.` can stand for: the same levels in the same rhythm. Only\n * that — ragnarok's 7 4 2 1 followed by a 7 4 2 is a figure of its own, with a\n * hairpin of its own.\n */\nfunction sameFigure(\n notes: readonly { start: number; volume: number }[],\n a: ShapedFigure,\n b: ShapedFigure\n): boolean {\n if (a.to - a.from !== b.to - b.from) return false;\n for (let i = 0; i <= a.to - a.from; i++) {\n if (notes[a.from + i].volume !== notes[b.from + i].volume) return false;\n if (\n i > 0 &&\n notes[a.from + i].start - notes[a.from + i - 1].start !==\n notes[b.from + i].start - notes[b.from + i - 1].start\n ) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Where a voice's level changes, as the marks a score prints.\n *\n * Only at a change, and never two within `DYNAMIC_HOLD`: the driver can move a\n * volume on every note, and a mark under every head is noise. Inside the hold\n * the LOUDER level stands — the accent is what a reader has to see — and a\n * change that comes straight back to the level before it is dropped.\n *\n * A shaped figure (`shapedFigures`) is written as its level and a hairpin under\n * the first, `sim.` under the next one just like it, its dashes running on over\n * the ones after that, until some other mark is printed. A figure that turns straight\n * into one going the other way — wookie hole's 6 4 2 1 2 4 6 8 on one held\n * note — is a level swaying, not a figure, and is read note by note as before.\n * After a hairpin the reader is where it ends, so going back to where it began\n * is written — ragnarok's mp over the 7 after 7 4 2 1 — unless a `sim.` that\n * goes on already says the figure comes round again.\n */\nexport function dynamicMarks(\n notes: readonly { start: number; volume: number }[],\n hold = DYNAMIC_HOLD\n): DynamicMark[] {\n const sorted = [...notes].sort((a, b) => a.start - b.start);\n const found = shapedFigures(sorted);\n const swaying = (a: ShapedFigure | undefined, b: ShapedFigure | undefined) =>\n !!a && !!b && b.from === a.to + 1 && a.words !== b.words;\n const figureAt = new Map<number, ShapedFigure>();\n found.forEach((figure, i) => {\n if (!swaying(found[i - 1], figure) && !swaying(figure, found[i + 1])) {\n figureAt.set(figure.from, figure);\n }\n });\n\n const marks: DynamicMark[] = [];\n // The level the reader is at.\n let heard: Dynamic | null = null;\n // The figure the last words were about, and whether its `sim.` has been printed.\n let stated: ShapedFigure | null = null;\n let similar = false;\n // A plain mark breaks a run of `sim.`; taken back, it gives the run back.\n const broken = new Map<DynamicMark, { stated: ShapedFigure | null; similar: boolean }>();\n const pop = () => {\n const mark = marks.pop()!;\n const run = broken.get(mark);\n if (run) ({ stated, similar } = run);\n };\n /**\n * The next figure after note `i` is one more like `like`, and nothing between says otherwise —\n * Intruder Excluder's 6 6 before each 6 4 2 1 is the same figure coming round, not news.\n */\n const starts = [...figureAt.keys()].sort((a, b) => a - b);\n const simGoesOn = (i: number, like: ShapedFigure) => {\n const next = starts.find((start) => start > i);\n if (next === undefined || !sameFigure(sorted, like, figureAt.get(next)!)) return false;\n const level = dynamicOf(sorted[i].volume);\n for (let k = i + 1; k < next; k++) if (dynamicOf(sorted[k].volume) !== level) return false;\n return true;\n };\n for (let i = 0; i < sorted.length; i++) {\n const note = sorted[i];\n const dynamic = dynamicOf(note.volume);\n const figure = figureAt.get(i);\n const last = marks[marks.length - 1];\n if (figure) {\n // `p`, and a beat later `mp` and a hairpin: the figure's mark says it, as the louder.\n // At the same level the mark stays and the hairpin goes on from it, bare.\n if (\n last &&\n !last.words &&\n note.start - last.tick < hold &&\n DYNAMICS.indexOf(last.dynamic) < DYNAMICS.indexOf(dynamic)\n ) {\n pop();\n // Its level is now the figure's to state.\n heard = marks[marks.length - 1]?.dynamic ?? null;\n }\n const until = sorted[figure.to].start;\n if (stated && sameFigure(sorted, stated, figure)) {\n if (similar) marks[marks.length - 1].until = until;\n else marks.push({ tick: note.start, dynamic, words: 'sim.', until });\n similar = true;\n } else {\n const mark: DynamicMark = { tick: note.start, dynamic, words: figure.words, until };\n if (heard === dynamic) mark.bare = true;\n marks.push(mark);\n stated = figure;\n similar = false;\n }\n // The hairpin has taken the reader down (or up) to where the figure ends.\n heard = dynamicOf(sorted[figure.to].volume);\n i = figure.to;\n continue;\n }\n if (heard === dynamic) continue;\n // Back at the level of a run of `sim.` that goes on: the `sim.` says so already.\n if (stated && dynamic === dynamicOf(sorted[stated.from].volume) && simGoesOn(i, stated)) {\n heard = dynamic;\n continue;\n }\n heard = dynamic;\n if (last && !last.words && note.start - last.tick < hold) {\n if (DYNAMICS.indexOf(dynamic) > DYNAMICS.indexOf(last.dynamic)) last.dynamic = dynamic;\n if (marks[marks.length - 2]?.dynamic === last.dynamic) pop();\n heard = marks[marks.length - 1].dynamic;\n continue;\n }\n const mark: DynamicMark = { tick: note.start, dynamic };\n broken.set(mark, { stated, similar });\n stated = null;\n marks.push(mark);\n }\n return marks;\n}\n\n/**\n * Where each NES noise period (`$400E`, 0..15) sits on the percussion staff:\n * high noise at the top and low noise at the bottom.\n */\nconst NOISE_LINES = [\n 'g/5',\n 'g/5',\n 'g/5',\n 'f/5',\n 'f/5',\n 'e/5',\n 'e/5',\n 'd/5',\n 'd/5',\n 'c/5',\n 'b/4',\n 'a/4',\n 'g/4',\n 'f/4',\n 'e/4',\n 'e/4',\n];\n\n/**\n * The notehead: a cross for a closed or pedal hat, a circled cross for an open\n * one, a plain head for everything with a skin. The pieces are the ones\n * `@xromdev/drumroll` draws on its kit (`NOISE_DRUM_KINDS`).\n */\nconst NOISE_HEADS = ['x', 'x', 'x', 'x', 'cx', 'cx', '', '', '', '', '', '', '', '', '', ''];\n\n/** A noise period as a VexFlow key on the percussion staff. Only the low nibble is the period. */\nexport function noiseKey(period: number): string {\n const index = period & 0x0f;\n return NOISE_HEADS[index] ? `${NOISE_LINES[index]}/${NOISE_HEADS[index]}` : NOISE_LINES[index];\n}\n\n/** A pitched note, with the volume it starts at when the channel has one. */\nexport interface ScoreNote extends TickNote {\n volume?: number;\n /** The note's pitch curve — `[position 0..1, semitones]` — as a piano roll draws it. */\n bend?: readonly (readonly [number, number])[];\n /** Grace notes in front of it, as MIDI numbers in the order they are played. */\n grace?: readonly number[];\n /** A repeat of the note before, quieter — an echo, written in brackets (`echoNotes`). */\n echo?: boolean;\n /**\n * Played short: its `ticks` are the value it is WRITTEN as, and it sounds for\n * less — a staccato dot over the head instead of a rest after it.\n */\n staccato?: boolean;\n}\n\n/** What a pitch curve is written as. `ticks` is the whole note's length, over which it moves. */\nexport type PitchEffect =\n | {\n kind: 'slide';\n /** Where it arrives, in semitones from the written pitch; to a tenth. */\n semitones: number;\n /** Where along the note the movement begins, 0..1. */\n from: number;\n ticks: number;\n /**\n * It lands on the next written note. When it does not — a sweep too wide to be a bend that\n * ends on no note (ragnarok's canyon, triangle, bar 15: E3 down to B2, then a D3) — the\n * staff draws where it lands as a small note in brackets. Set by `effectsOf`.\n */\n arrives?: boolean;\n }\n | {\n /** The pitch moves on the note it started on — a guitarist's bend, or its release downwards. */\n kind: 'bend';\n semitones: number;\n from: number;\n ticks: number;\n }\n | {\n kind: 'vibrato';\n depth: number;\n ticks: number;\n /**\n * The curve itself, `[position 0..1, semitones]`, kept for a vibrato wider than a semitone:\n * a wave glyph says nothing of a swing like Turbo Tunnel Race's, bar 31, a D6 going up four\n * semitones and down two and a half, so the staff draws the curve itself.\n */\n curve?: readonly (readonly [number, number])[];\n };\n\n/** A vibrato swinging further than this, in semitones, is drawn as its curve rather than a wave. */\nexport const WIDE_VIBRATO = 1;\n\n/**\n * A movement smaller than this, in semitones, is not written at all.\n *\n * 261 of the cartridge's 304 curves are a drift of a fifth of a semitone at the\n * end of a note. The roll draws them as a hairline, which is right for a picture\n * of the sound; on a staff a mark on every one of them would be noise over a\n * third of the notes of some tracks.\n */\nexport const DRIFT_LIMIT = 0.5;\n/** Changes of direction that make a curve a vibrato rather than a slide. */\nconst VIBRATO_TURNS = 3;\n/** A swing back smaller than this, in semitones, is the curve's own jitter, not a change of direction. */\nconst TURN_MIN = 0.25;\n/** The shallowest vibrato written, in semitones either way: Surf City's is a tenth. */\nconst LIGHT_VIBRATO = 0.09;\n\n/**\n * How many times a curve really changes direction.\n *\n * Counted with hysteresis: a move only turns once the curve has come back\n * `TURN_MIN` from the furthest point it reached. Counting every sign change of\n * the slope read ragnarok's canyon's triangle, bar 15 — a flicker of 0.05\n * semitones and then a steady fall of five to a B — as a vibrato, and it was\n * drawn as a wave where a reader sees a glissando.\n */\nfunction turnsOf(values: readonly number[], turnMin = TURN_MIN): number {\n let turns = 0;\n let direction = 0;\n let pivot = values[0] ?? 0;\n for (const value of values) {\n const move = value - pivot;\n if (direction === 0) {\n if (Math.abs(move) >= turnMin) {\n direction = Math.sign(move);\n pivot = value;\n }\n } else if (Math.sign(move) === direction) {\n pivot = value;\n } else if (Math.abs(move) >= turnMin) {\n turns++;\n direction = -direction;\n pivot = value;\n }\n }\n return turns;\n}\n\n/**\n * A note's pitch curve read as notation: a slide to where it arrives, a\n * vibrato, or nothing.\n *\n * Over the twenty tracks that is 33 slides (one to four semitones), 10 vibratos,\n * and the drifts left out — the same split the Battletoads music tooling\n * makes between a slide and a vibrato.\n */\n/** How far into a note a strike may reach and still be read as its attack, 0..1. */\n/**\n * Alien 3's kick takes three frames of a seventeen-frame bass note — 18% — and at 15% the\n * vibrato after it was still read with the kick in it.\n */\nexport const STRIKE_SHARE = 0.25;\n\n/**\n * The curve without the strike it opens with, if it opens with one: a pitch\n * away from the note at its first point that comes back to it within\n * `STRIKE_SHARE` of the note. That is how a sound driver hits a note — a\n * triangle bass kicked from an octave up, a frame of a deep thump — and it is\n * timbre, not a movement of the pitch: Alien 3's vibrato on a long G3 read six\n * semitones deep with the kick in front of it, and was drawn as a curve.\n */\nfunction withoutStrike(\n curve: readonly (readonly [number, number])[]\n): readonly (readonly [number, number])[] {\n if (Math.abs(curve[0][1]) < DRIFT_LIMIT) return curve;\n const back = curve.findIndex(([, semitones]) => Math.abs(semitones) < 0.05);\n if (back <= 0 || curve[back][0] > STRIKE_SHARE) return curve;\n return curve.slice(back);\n}\n\nexport function pitchEffect(\n whole: readonly (readonly [number, number])[],\n ticks: number\n): PitchEffect | null {\n const curve = whole.length >= 2 ? withoutStrike(whole) : whole;\n if (curve.length < 2) return null;\n const values = curve.map(([, semitones]) => semitones);\n const peak = Math.max(...values.map(Math.abs));\n if (peak < DRIFT_LIMIT) {\n /*\n * Under half a semitone a curve is not written — unless it SWINGS. Surf City wobbles a tenth of\n * a semitone and Intermission a sixth, both audible; wookie hole's\n * and ragnarok's marks, which a looser rule also calls vibrato, are one-way drifts at the end\n * of a two-tick note and stay unwritten. Turns tell the two apart, counted against the curve's\n * OWN depth: a fixed grain either misses a tenth-of-a-semitone swing or counts a drift's jitter.\n */\n return peak >= LIGHT_VIBRATO && turnsOf(values, peak / 2) >= VIBRATO_TURNS\n ? { kind: 'vibrato', depth: peak, ticks }\n : null;\n }\n\n if (turnsOf(values) >= VIBRATO_TURNS) {\n const depth = Math.max(...values.map(Math.abs));\n return depth > WIDE_VIBRATO\n ? { kind: 'vibrato', depth, ticks, curve }\n : { kind: 'vibrato', depth, ticks };\n }\n\n const end = values[values.length - 1];\n if (Math.abs(end) < DRIFT_LIMIT) return null;\n const moving = values.findIndex((semitones) => Math.abs(semitones) >= 0.1);\n const from = curve[Math.max(0, moving - 1)][0];\n return { kind: 'slide', semitones: Math.round(end * 10) / 10, from, ticks };\n}\n\n/** The most a note's pitch may move on its own and still be a bend: a tone and a half. */\nexport const BEND_MAX = 3;\n/** Ticks between a slide's end and the next note that still count as the slide arriving in it. */\nconst GLISS_GAP = 1;\n\n/**\n * Each note's effect, read against the note AFTER it in the part.\n *\n * A curve does not say whether the pitch is sliding somewhere or bending on the\n * spot; the music around it does. A slide that ends on the pitch the very next\n * note is written at arrives in that note — a glissando, as in the title music's\n * G4 up to A4. One that goes nowhere written is the note itself bending:\n * ragnarok's canyon, pulse 1, bar 5, a D#4 pulled up 1.3 semitones and then left\n * for an A3 — a guitarist's bend, which a reader said at once, where \"gliss.\" had\n * been printed. Past `BEND_MAX` nothing bends that far, and the sweeps of fifteen\n * to twenty-eight semitones that open a few tracks stay lines.\n *\n * Except when the note after it comes straight back to the pitch the curve left:\n * that is a bend and its release, however far it went. Clinger Winger, pulse 1,\n * an E2 pushed up six and a half semitones over four bars and then struck again\n * as E2 — a reader heard a bend where a line marked \"gliss.\" had been drawn.\n * Across the whole ROM this reads that one note differently and no other.\n */\nexport function effectsOf(notes: readonly ScoreNote[]): Map<number, PitchEffect> {\n const ordered = [...notes].sort((a, b) => a.start - b.start);\n const effects = new Map<number, PitchEffect>();\n ordered.forEach((note, index) => {\n const effect = note.bend ? pitchEffect(note.bend, note.ticks) : null;\n if (!effect) return;\n if (effect.kind === 'slide') {\n const next = ordered[index + 1];\n const follows = next !== undefined && next.start - (note.start + note.ticks) <= GLISS_GAP;\n const arrives = follows && Math.abs(next.midi - (note.midi + effect.semitones)) <= 0.5;\n const returns = follows && next.midi === note.midi;\n if (!arrives && (returns || Math.abs(effect.semitones) <= BEND_MAX)) {\n effects.set(note.start, { ...effect, kind: 'bend' });\n return;\n }\n effects.set(note.start, { ...effect, arrives });\n return;\n }\n effects.set(note.start, effect);\n });\n return effects;\n}\n\n/**\n * A bend's size, in semitones, to one decimal — the arrow says which way.\n *\n * Always the number. The guitar's words (½ for a semitone, \"full\" for a tone)\n * were printed for sizes near a step and the number for the rest, so one page\n * said \"½\" over a bend of 0.9 semitones and \"1.3\" over the next: two systems\n * side by side, and a \"½\" read as half a semitone.\n */\nexport function bendLabel(semitones: number): string {\n return Math.abs(semitones).toFixed(1);\n}\n\n/** The pitch movement a tied piece carries on from the head of its note. */\nexport interface EffectCarry {\n /** Where the note starts, and the pitch it is written at. */\n start: number;\n midi: number;\n effect: PitchEffect;\n}\n\n/** A staff item, with the pitch effect of the note it is the head of. */\nexport type ScoreItem = StaffItem & {\n effect?: PitchEffect;\n /**\n * On a piece tied on after the head: the movement it is part of, when that movement is drawn\n * along the note — a glissando or a bend held a bar or more — so a line that runs onto the next\n * system can be carried on there and land where the note ends.\n */\n carry?: EffectCarry;\n /** On a grand staff's voice: the stave the item stands on — see `crossStaffVoice`. */\n staff?: 'treble' | 'bass';\n /** The grace notes of the note this is the head of — see `ScoreNote.grace`. */\n grace?: readonly number[];\n /** The note is leaned on — see `accentedStarts`. */\n accent?: boolean;\n /** The note is an echo — see `ScoreNote.echo`. Its head is written in brackets. */\n echo?: boolean;\n /** The note is played short — see `ScoreNote.staccato`. A dot over its head. */\n staccato?: boolean;\n /**\n * The other heads on this one's stem, struck at the same moment: on a percussion staff, drums by\n * period — a cartridge plays its noise channel and its DMC samples at once, a hat over a kick; on\n * a pitched staff, notes by MIDI number — a violin's double and triple stops.\n */\n chord?: readonly number[];\n /**\n * The APU level the note STARTS at, 0..15, as the ROM holds it — for a renderer to print under\n * the head when asked. The dynamics are a reading of these numbers in six steps, which is what a\n * player needs; the number itself is what the cartridge says, and the two answer different\n * questions. Only on a head, and only where the channel has a volume at all: the triangle has\n * none, so its notes carry nothing.\n */\n volume?: number;\n /** Its beam runs across the bar line — see `crossBarRuns`. */\n across?: 'start' | 'join';\n /** Beams are grouped by this number rather than by the beat — see `accentBeamGroups`. */\n beamGroup?: number;\n};\n\n/**\n * How much louder than BOTH its neighbours a note has to start to be written as\n * accented, in nibble steps.\n *\n * Three is the step the tracks themselves use: the driver holds a level and\n * drops or lifts the next note by 3 — ragnarok's canyon, bar 25, alternates 4\n * and 7 through the bar, and 7 against 4 is what the ear hears as the accent.\n */\nexport const ACCENT_STEP = 3;\n\n/**\n * The notes a voice leans on: louder than the note before it by `ACCENT_STEP`,\n * no quieter than the note after it, and NOT on a beat.\n *\n * Off the beat is the whole point. The driver moves the volume constantly, and\n * a mark on every rise would put one under a third of the heads of some tracks\n * while saying nothing a reader cannot see from the dynamics. What a reader\n * cannot see is a voice that leans between the beats: ragnarok's canyon, bar 25,\n * plays sixteenths at 9 9 7 7 4 7 4 7 4 2 7 7 4 7 4 9 — every beat of the bar\n * but the first is a 4, and the 7s fall in the gaps. On paper that is an even\n * run of sixteenths; in the ears it is a syncopation, and accents are what make\n * the two agree.\n *\n * Read on the notes as the staff has them — after `voicePhase` has taken out a\n * channel's authored delay — or a voice written a tick late would count as\n * off the beat throughout.\n */\nexport function accentedStarts(\n notes: readonly ScoreNote[],\n beat = TICKS_PER_QUARTER,\n step = ACCENT_STEP\n): Set<number> {\n const sounded = [...notes]\n .filter((note): note is ScoreNote & { volume: number } => note.volume !== undefined)\n .sort((a, b) => a.start - b.start);\n const starts = new Set<number>();\n sounded.forEach((note, index) => {\n const before = sounded[index - 1];\n const after = sounded[index + 1];\n if (!before || !after) return;\n if (note.start % beat === 0) return;\n if (note.volume - before.volume < step) return;\n if (note.volume < after.volume) return;\n starts.add(note.start);\n });\n return starts;\n}\n\n/**\n * Beam groups that follow the ACCENTS rather than the beat, for a passage that\n * is written in one pulse and played in another.\n *\n * Ragnarok's canyon from bar 25 is the case, and it is a case, not a rule:\n * beats 2, 3 and 4 of every bar sit at volume 4 while the notes between them\n * are at 7, so beaming by the quarter draws four even groups over a bar whose\n * weight lands in five uneven ones — 3 2 3 3 2, each beginning on a note the\n * ROM leans on. Tried as a general rule over the cartridge it made beams of 14,\n * 16 and 32 heads elsewhere (wookie hole, Arctic Caverns), which is why the\n * passage asks for it by tick.\n *\n * Numbers a group per head from `from` on: a new one at every accent, and one\n * after the bar's LOUDEST head when what follows is quieter — the figure's own\n * peak, which ends a group rather than joining the run under it. Bar 25 is the\n * one that needs the second rule: bars 26 to 28 open on the two heads a beam\n * has already carried over the bar line, while 25 opens on the same pair with\n * nothing to carry them, and without it they were swallowed by the five heads\n * up to the first accent.\n */\nexport function accentBeamGroups(\n bars: ScoreItem[][],\n /** The passage the rule covers, in the staff's ticks: `[from, to)`. */\n { from, to }: { from: number; to: number },\n /** Each head's volume by its start tick — the levels the groups are read from. */\n levels: ReadonlyMap<number, number>\n): ScoreItem[][] {\n let group = 0;\n return bars.map((items) => {\n const within = (item: ScoreItem) => item.start >= from && item.start < to;\n const heads = items.filter((item) => item.midi !== null && within(item));\n /*\n * A voice with nothing to lean on keeps the beat. The rule has cuts only where a voice pushes,\n * and the triangle holds one level right through this passage: numbered along with the others\n * it had no cut at all, and its bar came out under a single beam from end to end.\n */\n if (!heads.some((item) => item.accent)) return items;\n const peak = Math.max(...heads.map((item) => levels.get(item.start) ?? 0), 0);\n let previous: number | null = null;\n return items.map((item) => {\n if (!within(item) || item.midi === null) return item;\n const level = levels.get(item.start);\n if (item.accent || (previous !== null && previous >= peak && (level ?? 0) < previous))\n group++;\n previous = level ?? previous;\n return { ...item, beamGroup: group };\n });\n });\n}\n\n/** The most notes a beam is carried across a bar line onto — the figure, and no more. */\nexport const CROSS_BAR_RUN = 4;\n\n/**\n * Figures a bar line cuts in half: a run that starts on the bar's last note and\n * carries the same level into the next bar.\n *\n * Beams do not cross bar lines, and for good reason — the bar line is what a\n * reader counts from. The exception earns itself when the figure is plainly one\n * gesture and the bar line falls inside it: ragnarok's canyon, bars 25 to 28,\n * ends each bar on an accented E3 and opens the next with D3 E3 at the same\n * level 9, the run around it sitting at 7 and 4. Three heads, one gesture, and\n * written bar by bar it reads as a stray sixteenth and a pair.\n *\n * Narrow on purpose: the last note must be ACCENTED (see `accentedStarts`), the\n * run must be unbroken, every note must hold the same volume, and it stops after\n * `CROSS_BAR_RUN` heads. Over the whole cartridge that is three places, all of\n * them this figure. Loosened to \"the level holds\" alone it caught 148, some of\n * them 240 notes long — a beam over half a track.\n *\n * Returns the start tick of each note in a crossing run, mapped to its part in\n * it: the `start` is the note the beam leaves the bar on, the `join`s are the\n * heads it reaches on the other side.\n */\nexport function crossBarRuns(\n notes: readonly ScoreNote[],\n grid: BarGrid,\n accents: ReadonlySet<number> = accentedStarts(notes)\n): Map<number, 'start' | 'join'> {\n const sounded = [...notes]\n .filter((note): note is ScoreNote & { volume: number } => note.volume !== undefined)\n .sort((a, b) => a.start - b.start);\n const runs = new Map<number, 'start' | 'join'>();\n sounded.forEach((note, index) => {\n if (note.ticks >= TICKS_PER_QUARTER || !accents.has(note.start)) return;\n const next = sounded[index + 1];\n if (!next || next.start !== note.start + note.ticks) return;\n if (barAt(grid, next.start) === barAt(grid, note.start)) return;\n if (next.volume !== note.volume) return;\n const chain: ScoreNote[] = [note];\n for (let at = index + 1; at < sounded.length && chain.length < CROSS_BAR_RUN; at++) {\n const head = sounded[at];\n const before = chain[chain.length - 1];\n if (head.start !== before.start + before.ticks || head.volume !== note.volume) break;\n chain.push(head);\n }\n if (chain.length < 2) return;\n runs.set(note.start, 'start');\n for (const head of chain.slice(1)) runs.set(head.start, 'join');\n });\n return runs;\n}\n\n/** Whether an effect is drawn along its note — and so has to carry on where the note does. */\nexport function drawnAlong(effect: PitchEffect, measureTicks = MEASURE_TICKS): boolean {\n return (\n effect.kind === 'slide' ||\n (effect.kind === 'bend' && effect.ticks >= measureTicks) ||\n (effect.kind === 'vibrato' && effect.curve !== undefined)\n );\n}\n\n/**\n * Puts what each note carries on its HEAD — the first piece of it, never a\n * piece tied on after a bar line, which would mark one note twice: its effect,\n * grace notes, accent, echo, level, and its part in a beam across the bar line.\n * The pieces tied on after a head get a `carry` instead, when the effect is\n * drawn along the note.\n *\n * In place, and in one walk: the bars are the ones `buildScore` has just made,\n * and copying every head once for each thing it might carry was a fifth of the\n * time a score took to work out. The marks go on in the order above, so a\n * head's fields read the same whichever of them it has.\n */\nfunction attachHeads(\n bars: StaffItem[][],\n marks: {\n effects?: ReadonlyMap<number, PitchEffect>;\n graces?: ReadonlyMap<number, readonly number[]>;\n accents?: ReadonlySet<number>;\n echoes?: ReadonlySet<number>;\n levels?: ReadonlyMap<number, number>;\n across?: ReadonlyMap<number, 'start' | 'join'>;\n staccatos?: ReadonlySet<number>;\n chords?: ReadonlyMap<number, readonly number[]>;\n }\n): ScoreItem[][] {\n const effects = marks.effects?.size ? marks.effects : null;\n const graces = marks.graces?.size ? marks.graces : null;\n const accents = marks.accents?.size ? marks.accents : null;\n const echoes = marks.echoes?.size ? marks.echoes : null;\n const levels = marks.levels?.size ? marks.levels : null;\n const across = marks.across?.size ? marks.across : null;\n const staccatos = marks.staccatos?.size ? marks.staccatos : null;\n const chords = marks.chords?.size ? marks.chords : null;\n if (!effects && !graces && !accents && !echoes && !levels && !across && !staccatos && !chords) {\n return bars;\n }\n let active: EffectCarry | null = null;\n for (const items of bars) {\n for (const plain of items) {\n const item = plain as ScoreItem;\n const head = item.midi !== null && !item.tieStop;\n if (effects) {\n if (head && effects.has(item.start)) {\n const effect = effects.get(item.start)!;\n active = drawnAlong(effect) ? { start: item.start, midi: item.midi!, effect } : null;\n item.effect = effect;\n } else if (active && item.tieStop && item.midi === active.midi) {\n item.carry = active;\n } else if (!item.tieStop) {\n active = null;\n }\n }\n if (!head) continue;\n if (graces?.has(item.start)) item.grace = graces.get(item.start);\n if (accents?.has(item.start)) item.accent = true;\n if (echoes?.has(item.start)) item.echo = true;\n if (levels?.has(item.start)) item.volume = levels.get(item.start);\n if (across?.has(item.start)) item.across = across.get(item.start);\n if (staccatos?.has(item.start)) item.staccato = true;\n if (chords?.has(item.start)) item.chord = chords.get(item.start);\n }\n }\n return bars;\n}\n\n/** Each note's own APU level by where it starts — what `attachHeads` puts on its head. */\nfunction levelsOf(notes: readonly { start: number; volume?: number }[]): Map<number, number> {\n const levels = new Map<number, number>();\n for (const note of notes) if (note.volume !== undefined) levels.set(note.start, note.volume);\n return levels;\n}\n\n/** A noise hit: when, for how long, and which `$400E` period. */\nexport interface ScoreHit {\n start: number;\n ticks: number;\n period: number;\n /** The APU level the hit starts at, 0..15 — see `ScoreItem.volume`. */\n volume?: number;\n}\n\nexport type ScoreStaveKind = 'treble' | 'bass' | 'percussion';\n\nexport interface ScoreStave {\n partId: string;\n kind: ScoreStaveKind;\n /**\n * One list of items per bar. Filled to the bar line — except on a grand\n * staff, where it is only what stands on THIS stave, for the layout.\n */\n bars: ScoreItem[][];\n /** On a grand staff's upper stave: the part's whole voice, filled to the bar line, drawn across both. */\n voiceBars?: ScoreItem[][];\n /** On a grand staff's lower stave: its notes belong to the voice of the stave above. */\n follows?: boolean;\n}\n\nexport interface ScoreModel {\n /** Ticks added to the piece's clock to get the score's — see `staffShift`. */\n shift: number;\n /** Where the bar lines fall: the metre, and the opening bar's own length. */\n grid: BarGrid;\n barCount: number;\n staves: ScoreStave[];\n /** Each part's marks, in the SCORE's ticks. */\n dynamics: Record<string, DynamicMark[]>;\n /**\n * Each part's own delay taken out (`voicePhase`), in ticks: its notes sit\n * this much EARLIER on the staff than on the piece's clock. Anything that\n * compares a staff tick with the piece's — hiding what has not been read\n * yet — has to take it out too.\n */\n phases: Record<string, number>;\n}\n\n/** Where a piece changes key: the tick the new key starts on, and its VexFlow name. */\nexport interface KeyChange {\n /** In the PIECE's ticks, as the ROM holds them. */\n tick: number;\n key: string;\n}\n\n/**\n * The key each bar of a score is written in.\n *\n * A change takes effect from the bar its tick falls in — the tick is moved onto\n * the staff's clock by `shift` first — so it stays with the music when the bar\n * line or the metre is read differently. Volkmire's Inferno Race turns from D\n * minor to D major on tick 870, which is bar 29 of its 2/4 score.\n */\nexport function barKeys(\n barCount: number,\n shift: number,\n grid: BarGrid,\n opening: string,\n changes: readonly KeyChange[] = []\n): string[] {\n const names = Array.from({ length: barCount }, () => opening);\n for (const change of changes) {\n const from = Math.max(0, barAt(grid, change.tick + shift));\n for (let bar = from; bar < names.length; bar++) names[bar] = change.key;\n }\n return names;\n}\n\n/** The part id the percussion staff carries. */\nexport const DRUMS_PART = 'drums';\n\n/** How a score is barred and read — everything `buildScore` takes beyond the notes. */\nexport interface ScoreOptions {\n /** The tick the bar lines are counted from. Default 0. */\n offset?: number;\n /** Ticks in a bar: 64 is 4/4, 32 is 2/4. Default `MEASURE_TICKS`. */\n measureTicks?: number;\n /**\n * Write the pickup as part of the opening bar rather than in a bar of its own.\n *\n * The music then starts on the score's first tick, and the opening bar is as\n * much longer than the metre as the pickup is — one bar of 19/32 in front of\n * Volkmire's Inferno Race's 2/4, instead of a bar of rests with the run in it.\n */\n mergePickup?: boolean;\n /**\n * The passage read by its accents: the only place accents are marked (`accentedStarts`), and\n * where the beams follow them rather than the beat (`accentBeamGroups`). None given, no accents.\n * In the PIECE's ticks, like everything a caller gives; `shift` moves it onto the staff's clock.\n */\n accentBeams?: { from: number; to: number };\n /** Bars later in the piece with a length of their own — see `BarGrid`. */\n oddBars?: readonly OddBar[];\n /**\n * Take a part's own delay of up to `MAX_PHASE` ticks out (`voicePhase`). Default true: a sound\n * driver delays a channel a tick or two on purpose, and the staff writes it on the beat. Music\n * that is already on its beat — a MIDI file — wants it off, or a voice is moved off the beat it\n * keeps.\n */\n alignVoices?: boolean;\n}\n\n/**\n * The whole score, worked out once.\n *\n * `options.offset` is the tick the bar lines are counted from and\n * `options.measureTicks` the length of a bar; any other notation view of the\n * same piece should use the same two, so they all bar the music the same way.\n */\nexport function buildScore(\n parts: readonly {\n id: string;\n notes: readonly ScoreNote[];\n /** Which staves, when the caller decides rather than the notes (`partStaves`). */\n staves?: readonly ('treble' | 'bass')[];\n }[],\n drums: readonly ScoreHit[],\n totalTicks: number,\n {\n offset = 0,\n measureTicks = MEASURE_TICKS,\n mergePickup = false,\n accentBeams,\n oddBars = [],\n alignVoices = true,\n }: ScoreOptions = {}\n): ScoreModel {\n const { grid, shift } = barring(offset, measureTicks, mergePickup, oddBars);\n const end = totalTicks + shift;\n const barCount = barCountOf(grid, end);\n const barsOf = (notes: readonly TickNote[]) =>\n staffMeasures(staffItems(notes, end, grid), end, grid).map((bar) => bar.items);\n const phases: Record<string, number> = {};\n const moved = <T extends TickNote>(notes: readonly T[], id?: string): T[] => {\n const phase = alignVoices && notes.length > 0 ? voicePhase(notes, offset, measureTicks) : 0;\n if (id !== undefined) phases[id] = phase;\n return shiftNotes(notes, shift - phase);\n };\n\n const staves: ScoreStave[] = [];\n const dynamics: Record<string, DynamicMark[]> = {};\n\n for (const part of parts) {\n /*\n * Notes struck together are one head with a chord on its stem: the highest — the line a\n * reader follows — is the head the rhythm, the staff and the marks are read from, and it\n * holds as long as the longest of them. A part with one note at a time is untouched.\n */\n const together = new Map<number, ScoreNote[]>();\n for (const note of part.notes)\n together.set(note.start, [...(together.get(note.start) ?? []), note]);\n const groups = [...together.values()];\n const leads = groups.map((group) =>\n group.length === 1\n ? group[0]\n : {\n ...group.reduce((top, note) => (note.midi > top.midi ? note : top)),\n ticks: Math.max(...group.map((note) => note.ticks)),\n }\n );\n const notes = moved(leads, part.id);\n const pitchChords = new Map<number, number[]>();\n groups.forEach((group, index) => {\n if (group.length < 2) return;\n const others = [...new Set(group.map((note) => note.midi))]\n .filter((midi) => midi !== leads[index].midi)\n .sort((a, b) => a - b);\n if (others.length) pitchChords.set(notes[index].start, others);\n });\n const range = pitchChords.size\n ? [...notes, ...[...pitchChords.values()].flat().map((midi) => ({ midi }))]\n : notes;\n const kinds = part.staves ? [...part.staves] : partStaves(range);\n // Read over the whole part: the note after a slide may be on the other staff.\n const effects = effectsOf(notes);\n /*\n * Accents only inside the passage read by its accents (`accentBeams`) — a\n * reading by ear, made for ragnarok's canyon, bars 25 to 28. Let loose over\n * the cartridge the rule marked every loud note off the beat, and Arctic\n * Caverns' echo — every second note far quieter than the one before, an\n * imitation of an echo — came out as a column of accents it does not have.\n */\n const accents = accentBeams\n ? new Set(\n [...accentedStarts(notes)].filter(\n (start) => start >= accentBeams.from + shift && start < accentBeams.to + shift\n )\n )\n : new Set<number>();\n const across = crossBarRuns(notes, grid, accents);\n const heads = () => {\n const written = attachHeads(barsOf(notes), {\n effects,\n graces: new Map(\n notes.filter((note) => note.grace?.length).map((note) => [note.start, note.grace!])\n ),\n accents,\n echoes: new Set(notes.filter((note) => note.echo).map((note) => note.start)),\n levels: levelsOf(notes),\n across,\n staccatos: new Set(notes.filter((note) => note.staccato).map((note) => note.start)),\n chords: pitchChords,\n });\n if (!accentBeams) return written;\n return accentBeamGroups(\n written,\n { from: accentBeams.from + shift, to: accentBeams.to + shift },\n levelsOf(notes)\n );\n };\n if (kinds.length === 1) {\n staves.push({ partId: part.id, kind: kinds[0], bars: heads() });\n } else {\n const voice = crossStaffVoice(heads());\n const on = (staff: 'treble' | 'bass') =>\n voice.map((items) => items.filter((item) => item.staff === staff));\n staves.push({\n partId: part.id,\n kind: 'treble',\n bars: on('treble'),\n voiceBars: voice,\n });\n staves.push({\n partId: part.id,\n kind: 'bass',\n bars: on('bass'),\n follows: true,\n });\n }\n const loud = notes.filter(\n (note): note is ScoreNote & { volume: number } => note.volume !== undefined\n );\n dynamics[part.id] = dynamicMarks(loud);\n }\n\n if (drums.length > 0) {\n /*\n * Hits at the same moment are one chord: the longest is the head the staff's rhythm is\n * written from, the others stand on its stem. A staff of one voice wrote them one after\n * another, and every hat over a kick pushed the rest of the bar a value late.\n */\n const groups = new Map<number, ScoreHit[]>();\n for (const hit of drums) groups.set(hit.start, [...(groups.get(hit.start) ?? []), hit]);\n const leads = [...groups.values()].map((group) =>\n group.reduce((longest, hit) => (hit.ticks > longest.ticks ? hit : longest))\n );\n const others = [...groups.values()].map((group, index) => [\n ...new Set(\n group\n .filter((hit) => hit !== leads[index])\n .map((hit) => hit.period & 0x0f)\n .filter((period) => period !== (leads[index].period & 0x0f))\n ),\n ]);\n const hits = moved(\n leads.map((hit) => ({\n start: hit.start,\n ticks: hit.ticks,\n midi: hit.period & 0x0f,\n volume: hit.volume,\n }))\n );\n const chords = new Map<number, number[]>();\n hits.forEach((hit, index) => {\n if (others[index]?.length) chords.set(hit.start, others[index]);\n });\n /*\n * A drum is struck once. What is left of its slot after the first head —\n * the rest of a long value, or the part carried over a bar line — is\n * written as rest: tied on a percussion staff it reads as a roll, and as a\n * second head it reads as a second hit.\n */\n const bars = attachHeads(\n barsOf(hits).map((items) =>\n items.map((item) =>\n item.tieStop\n ? { ...item, midi: null, tieStart: false, tieStop: false }\n : { ...item, tieStart: false }\n )\n ),\n { levels: levelsOf(hits), chords }\n );\n staves.push({ partId: DRUMS_PART, kind: 'percussion', bars });\n }\n\n return { shift, grid, barCount, staves, dynamics, phases };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,59 @@
1
1
  {
2
2
  "name": "@xromdev/notation",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Notes in ticks, read as a score: note values, ties, tuplets, bar lines, key spelling, clefs, grand staff and dynamics — no DOM, no renderer.",
5
+ "license": "MIT",
6
+ "author": "Oleksandr Maksymov",
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "./package.json": "./package.json"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "sideEffects": false,
24
+ "scripts": {
25
+ "build": "tsc -p tsconfig.build.json",
26
+ "test": "vitest run",
27
+ "typecheck": "tsc -p tsconfig.json --noEmit",
28
+ "prepare": "npm run build",
29
+ "prepublishOnly": "npm run typecheck && npm test"
30
+ },
31
+ "keywords": [
32
+ "music-notation",
33
+ "sheet-music",
34
+ "score",
35
+ "musicxml",
36
+ "vexflow",
37
+ "midi",
38
+ "nes",
39
+ "chiptune"
40
+ ],
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/DeepNESReverse/xrom-notation.git"
44
+ },
45
+ "homepage": "https://github.com/DeepNESReverse/xrom-notation#readme",
46
+ "bugs": {
47
+ "url": "https://github.com/DeepNESReverse/xrom-notation/issues"
48
+ },
49
+ "engines": {
50
+ "node": ">=18"
51
+ },
52
+ "devDependencies": {
53
+ "typescript": "^5.9.3",
54
+ "vitest": "^3.2.7"
55
+ },
56
+ "publishConfig": {
57
+ "access": "public"
58
+ }
59
+ }