Write the staff one octave below sounding pitch.
AppImage release / appimage (push) Successful in 54s

Sounding C5 sits on the ledger line below the treble staff. Sharps and flats move with the note. Fingerings and the foot-up charts stay as they are. Version 0.2.2.

Co-authored-by: catpersonisme <catpersonisme@gmail.com>
This commit is contained in:
Cursor Agentandchen committed 2026-10-11 10:08:19 +00:00
1 parent dcca7f5e83
commit e51fdf8216
6 files changed
+32 -26

No files matched your search

+12 -7
View File
@@ -8,13 +8,15 @@ const RECORDER_VB_H = 188;
export const STAFF_SPACE = 4.6;
const STEP = STAFF_SPACE / 2;
const TOP_INDEX = 20;
const LOW_STEM_STEPS = 7;
const PAD_TOP = 4;
const PAD_BOTTOM = 8;
/** Highest written note is sounding D7, drawn as D6. */
const TOP_INDEX = 13;
/** Lowest written note is sounding C5, drawn as C4 on the ledger line below. */
const LOW_INDEX = -2;
const PAD_TOP = 6;
const PAD_BOTTOM = 14;
const ABOVE = TOP_INDEX * STEP;
const BELOW = LOW_STEM_STEPS * STEP - 5 * STEP + PAD_BOTTOM;
const BELOW = -LOW_INDEX * STEP + PAD_BOTTOM;
export const BOTTOM_LINE_Y = RECORDER_VB_H + 3 + PAD_TOP + ABOVE;
export const CHART_VB_H = Math.ceil(BOTTOM_LINE_Y + BELOW);
@@ -31,7 +33,10 @@ const LETTERS = ["C", "D", "E", "F", "G", "A", "B"] as const;
export type Accidental = "sharp" | "flat";
/** Treble staff. Index 0 is the bottom line, E4. C5, the recorder's low C, is 5. */
/**
* Treble staff, written one octave below sounding pitch.
* Index 0 is the bottom line, E4. Sounding C5 is written C4, index -2.
*/
export function staffPlacement(pitch: string): { index: number; accidental: Accidental | null } | null {
const match = /^([A-Ga-g])(#|b|♯|♭)?(-?\d+)$/.exec(pitch.trim());
if (!match) return null;
@@ -41,7 +46,7 @@ export function staffPlacement(pitch: string): { index: number; accidental: Acci
mark === "#" || mark === "♯" ? "sharp" : mark === "b" || mark === "♭" ? "flat" : null;
const octave = Number(match[3]);
if (!Number.isInteger(octave)) return null;
const diatonic = (octave - 4) * 7 + LETTERS.indexOf(letter as (typeof LETTERS)[number]);
const diatonic = (octave - 1 - 4) * 7 + LETTERS.indexOf(letter as (typeof LETTERS)[number]);
return { index: diatonic - 2, accidental };
}