Draw fingering charts foot-up, in grouped rows.
AppImage release / appimage (push) Successful in 1m36s
AppImage release / appimage (push) Successful in 1m36s
The foot and the double holes sit at the top of each narrow chart, and the mouthpiece sits at the bottom, matching hand-drawn tabs. Which holes are open or closed is unchanged. A repeat mark is shown only when the score repeats. Version 0.1.2. Co-authored-by: catpersonisme <catpersonisme@gmail.com>
This commit is contained in:
9 files changed
+314
-122
No files matched your search
@@ -17,6 +17,10 @@ export type ScoreEvent = {
|
||||
export type Measure = {
|
||||
id: string;
|
||||
events: ScoreEvent[];
|
||||
/** A forward repeat barline stands at the start of this measure. */
|
||||
repeatForward?: boolean;
|
||||
/** A backward repeat ends on this measure. The number is how many times to play the passage. */
|
||||
repeatTimes?: number;
|
||||
};
|
||||
|
||||
export type ScoreOrigin = "sample" | "upload" | "blank";
|
||||
@@ -86,6 +90,33 @@ export function formatBeat(beat: number): string {
|
||||
return Number.isInteger(rounded) ? String(rounded) : String(rounded);
|
||||
}
|
||||
|
||||
/** Extra full beats after the note itself. A half note in 4/4 returns 1. A dotted quarter returns 0. */
|
||||
export function extraBeatArrows(quarters: number, timeSignature: TimeSignature): number {
|
||||
const perBeat = 4 / timeSignature.beatType;
|
||||
if (!(perBeat > 0) || !(quarters > 0)) return 0;
|
||||
const wholeBeats = Math.floor(quarters / perBeat + 1e-6);
|
||||
return Math.max(0, wholeBeats - 1);
|
||||
}
|
||||
|
||||
/** Group a lead into horizontal rows. A row holds about `budget` notes, and never splits a bar. */
|
||||
export function leadRows<T extends { events: { length: number } }>(measures: T[], budget = 14): T[][] {
|
||||
const rows: T[][] = [];
|
||||
let current: T[] = [];
|
||||
let count = 0;
|
||||
for (const measure of measures) {
|
||||
const notes = Math.max(1, measure.events.length);
|
||||
if (current.length > 0 && count + notes > budget) {
|
||||
rows.push(current);
|
||||
current = [];
|
||||
count = 0;
|
||||
}
|
||||
current.push(measure);
|
||||
count += notes;
|
||||
}
|
||||
if (current.length > 0) rows.push(current);
|
||||
return rows;
|
||||
}
|
||||
|
||||
export function blankScore(): Score {
|
||||
return {
|
||||
title: "Untitled line",
|
||||
|
||||
Reference in new issue
Block a user