pepperscore 0.2.0 → 0.4.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/CHANGELOG.md +74 -0
- package/LICENSE +26 -12
- package/README.md +127 -9
- package/dist/THIRD_PARTY_NOTICES.txt +1222 -0
- package/dist/assets/{import.worker-D0XfuAHu.js → import.worker-Rop-z7az.js} +2 -2
- package/dist/assets/verovio.worker-DQm-ikdG.js +7 -0
- package/dist/audio.d.ts +24 -0
- package/dist/audio.js +198 -0
- package/dist/audio.js.map +1 -0
- package/dist/components/InstrumentChooser.d.ts +17 -0
- package/dist/components/OctaveTool.d.ts +21 -0
- package/dist/components/PepperScore.d.ts +96 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3738 -3382
- package/dist/index.js.map +1 -1
- package/dist/instruments.d.ts +2 -0
- package/dist/instruments.js +2 -0
- package/dist/lib/chrome.d.ts +10 -2
- package/dist/lib/file-state.d.ts +45 -5
- package/dist/lib/header-controls.d.ts +7 -3
- package/dist/lib/hit-test.d.ts +18 -0
- package/dist/lib/instrument-model.d.ts +80 -0
- package/dist/lib/instrument-switch-state.d.ts +169 -0
- package/dist/lib/instrument-view.d.ts +92 -0
- package/dist/lib/instruments.d.ts +82 -0
- package/dist/lib/metronome.d.ts +33 -0
- package/dist/lib/notation/document.d.ts +11 -1
- package/dist/lib/notation/mei-spelling.d.ts +9 -1
- package/dist/lib/notation/mei-tab.d.ts +58 -0
- package/dist/lib/notation/mei-view.d.ts +8 -0
- package/dist/lib/playback/timeline.d.ts +4 -1
- package/dist/lib/prefs.d.ts +67 -0
- package/dist/lib/range-fit-core.d.ts +26 -0
- package/dist/lib/render.d.ts +36 -1
- package/dist/lib/score.d.ts +23 -1
- package/dist/lib/sound-players.d.ts +9 -1
- package/dist/lib/tab/fret-assign.d.ts +53 -0
- package/dist/lib/tab/tab-parts.d.ts +64 -0
- package/dist/lib/transpose.d.ts +3 -2
- package/dist/lib/verovio-protocol.d.ts +15 -0
- package/dist/lib/verovio-runtime.d.ts +9 -1
- package/dist/range-fit-core-B1rMWdI4.js +468 -0
- package/dist/range-fit-core-B1rMWdI4.js.map +1 -0
- package/dist/runtime-files.d.ts +15 -0
- package/dist/{sf2-player-CRlOJDhD.js → sf2-player-oWC6yrUH.js} +28 -6
- package/dist/sf2-player-oWC6yrUH.js.map +1 -0
- package/dist/sound-players-DdLBBZaR.js +1172 -0
- package/dist/sound-players-DdLBBZaR.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/verovio/LICENSE +858 -0
- package/dist/verovio/verovio-module.mjs +0 -0
- package/dist/verovio/verovio.mjs +397 -0
- package/package.json +14 -2
- package/dist/assets/verovio.worker-DkHQmOsT.js +0 -19034
- package/dist/sf2-player-CRlOJDhD.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Part, Score } from '../score';
|
|
1
|
+
import type { Part, Score, ScoreNote } from '../score';
|
|
2
2
|
import { type FeatureInventory, type SourceDiagnostic } from './musicxml-source';
|
|
3
3
|
export type { SourceDiagnostic };
|
|
4
4
|
export type SourceFormat = 'musicxml' | 'mxl' | 'mei' | 'abc' | 'midi' | 'sample';
|
|
@@ -32,6 +32,16 @@ export type SourceDocument = Readonly<{
|
|
|
32
32
|
identity: SourceIdentity;
|
|
33
33
|
readOriginalBytes: () => Uint8Array;
|
|
34
34
|
}>;
|
|
35
|
+
/**
|
|
36
|
+
* The MEI xml:id `scoreToMei` gives pitch `index` of a note (ABC, MIDI and demo scores, whose pitches carry no
|
|
37
|
+
* `sourceId`). Its continuations into later measures and the pieces of a split duration are separate MEI notes with
|
|
38
|
+
* `_cN` / `_sN` appended; `generatedPitchIdOf` maps those back to this id.
|
|
39
|
+
*/
|
|
40
|
+
export declare const generatedPitchId: (note: Pick<ScoreNote, "id" | "pitches">, index: number) => string;
|
|
41
|
+
/** The `generatedPitchId` an MEI note of `scoreToMei` was drawn for (its `_cN` / `_sN` suffixes removed), or null. */
|
|
42
|
+
export declare const generatedPitchIdOf: (meiId: string) => string | null;
|
|
43
|
+
/** Whether a document's engraving MEI was generated by `scoreToMei` from the Score (not an imported MEI or MusicXML). */
|
|
44
|
+
export declare const generatedEngraving: (doc: Pick<SourceDocument, "format" | "engravingFormat"> | undefined) => boolean;
|
|
35
45
|
/** Deterministic MEI staffDef ID for a Score part, so views can hide staves by identity. */
|
|
36
46
|
export declare const staffDefXmlId: (partId: string) => string;
|
|
37
47
|
/** Source feature inventory of an XML source (MusicXML, MXL member or MEI), read with the streaming tokenizer. */
|
|
@@ -9,13 +9,17 @@
|
|
|
9
9
|
* degrees, Fb/Cb only as passing notes in keys of 6+ flats, flats-only/sharps-only per key, no double accidentals;
|
|
10
10
|
* - accidentals are re-shown or cancelled within each measure to match the new spellings (@accid / @accid.ges);
|
|
11
11
|
* - chord symbols (`<harm>`) are respelled for their staff's key;
|
|
12
|
-
* - percussion staves never get a key signature or key change (in every view, transposed or not)
|
|
12
|
+
* - percussion staves never get a key signature or key change (in every view, transposed or not);
|
|
13
|
+
* - an instrument-switched staff (instrument-view.ts) moves by its own `shift`, takes the target's clef (the source's
|
|
14
|
+
* clef changes are dropped), and notes an octave move names (`octaves`) move by an octave, before accidentals are
|
|
15
|
+
* re-evaluated.
|
|
13
16
|
*
|
|
14
17
|
* Keys are rewritten from a per-staff timeline (the spec's Score keys, else the MEI's): every key signature is removed
|
|
15
18
|
* from the score definitions and each staff's keys are written where they start or change.
|
|
16
19
|
*
|
|
17
20
|
* String-level like mei-view.ts (the worker has no DOMParser); the input is Verovio's own `getMEI` output.
|
|
18
21
|
*/
|
|
22
|
+
import type { InstrumentClef } from '../instrument-model';
|
|
19
23
|
import { type KeyMode } from '../spelling';
|
|
20
24
|
import { type StaffSpelling } from './respell';
|
|
21
25
|
export type SpellingSpec = {
|
|
@@ -44,6 +48,10 @@ export type StaffSpec = StaffSpelling & {
|
|
|
44
48
|
* spellings, e.g. a B♭ trumpet in Ab sounding in F# with C double sharps), the way the Score view does.
|
|
45
49
|
*/
|
|
46
50
|
shift?: [number, number];
|
|
51
|
+
/** Octave moves of notes (instrument switch, range fit or the reader's): semitones by MEI note xml:id. */
|
|
52
|
+
octaves?: Record<string, 12 | -12>;
|
|
53
|
+
/** The staff's clef replaced by an instrument switch: set on its staff definitions, its clef changes removed. */
|
|
54
|
+
clef?: InstrumentClef;
|
|
47
55
|
};
|
|
48
56
|
/** Does this spec change anything for this MEI (a transposition, a flip, or a percussion staff with keys to strip)? */
|
|
49
57
|
export declare function spellingNeeded(mei: string, spec: SpellingSpec | undefined): boolean;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guitar TAB staves for the engraving view (docs/specs/guitar-tab.md, "Generation"). String-level like mei-view.ts:
|
|
3
|
+
* the Verovio worker has no DOMParser and the input is Verovio's own `getMEI` output, already spelled and transposed,
|
|
4
|
+
* so frets follow the pitches the reader shows.
|
|
5
|
+
*
|
|
6
|
+
* For every notation staff `n` in `TabSpec.generate`, a `tab.guitar` staff `100 + n` is added right after it (its
|
|
7
|
+
* staffDef after the notation staffDef, its staff after the notation staff in every measure). Each layer is cloned:
|
|
8
|
+
* a note or chord becomes a `tabGrp` (same duration) with a `tabDurSym` and one `note tab.course tab.fret` per pitch;
|
|
9
|
+
* beams, tuplets and rests are kept; grace notes, lyrics, clefs and everything else are dropped. IDs get a `-tab`
|
|
10
|
+
* suffix (`${note}-tabn` for the TAB note of a single note, whose `tabGrp` takes `${note}-tab`), so the reader finds
|
|
11
|
+
* the TAB event of a Score note by its source ID. Tie continuations keep their rhythm (the `tabGrp` and its stem) and
|
|
12
|
+
* show no fret: their TAB note, on the string of the note they continue, is invisible. Measure and beat repeats are
|
|
13
|
+
* copied, so the repeat sign shows on the TAB staff too.
|
|
14
|
+
*
|
|
15
|
+
* Frets come from the fingering solver (tab/fret-assign.ts), run over each staff's whole document in time order (all
|
|
16
|
+
* layers) so it sees the passage, not one measure. `tab.course`/`tab.fret` already on notation notes (MusicXML
|
|
17
|
+
* `<technical>` string/fret) are fixed constraints. `retarget` moves staff-bound text (chord symbols, tempo,
|
|
18
|
+
* directions, fermatas) of a notation staff that the view hides onto its TAB staff; an event attached to a note
|
|
19
|
+
* (`startid`) is attached to that note's TAB event.
|
|
20
|
+
*
|
|
21
|
+
* `refret` re-fingers imported TAB staves that double no notation staff (a TAB-only score) when the view transposes:
|
|
22
|
+
* their notes' sounding pitches (the staff's `<tuning>` plus fret) move by the given semitones and are solved again.
|
|
23
|
+
*/
|
|
24
|
+
import { type FretPos } from '../tab/fret-assign';
|
|
25
|
+
export type TabSpec = {
|
|
26
|
+
/** Notation staff numbers (`@n`) that get a generated TAB staff `100 + n`. */
|
|
27
|
+
generate: string[];
|
|
28
|
+
/** Staff-bound control events of a hidden notation staff move to this TAB staff (`n` → TAB `n`). */
|
|
29
|
+
retarget: Record<string, string>;
|
|
30
|
+
/** Open-string MIDI pitches, low to high. */
|
|
31
|
+
tuning: number[];
|
|
32
|
+
/** Capo fret; frets are relative to it. */
|
|
33
|
+
capo: number;
|
|
34
|
+
/** Use `tab.course`/`tab.fret` already on notation notes as fixed fingerings (false when the view moved pitches). */
|
|
35
|
+
fixed: boolean;
|
|
36
|
+
/** Generated staves whose `tab.course`/`tab.fret` do not apply even when `fixed` (an instrument view moved their notes). */
|
|
37
|
+
unfixed?: string[];
|
|
38
|
+
/**
|
|
39
|
+
* Generated staves whose notes are already at sounding pitch (the concert view of a transposing part): their
|
|
40
|
+
* `trans.semi` was applied by spelling and must not be applied again.
|
|
41
|
+
*/
|
|
42
|
+
sounding?: string[];
|
|
43
|
+
/**
|
|
44
|
+
* Generated staves of a part switched to another instrument (instrument-view.ts), by `@n`: semitones from their
|
|
45
|
+
* spelled (shown) pitch to sounding pitch, which replace `trans.semi` (a guitar in the written view: -12).
|
|
46
|
+
*/
|
|
47
|
+
switched?: Record<string, number>;
|
|
48
|
+
/** Imported TAB staves (no notation partner) to re-finger, by staff `@n`: the semitones their pitches move. */
|
|
49
|
+
refret?: Record<string, number>;
|
|
50
|
+
};
|
|
51
|
+
/** Fingerings by notation note `xml:id`, kept across chunk documents so a note keeps its fret wherever it is drawn. */
|
|
52
|
+
export type FretMemory = Map<string, FretPos>;
|
|
53
|
+
/**
|
|
54
|
+
* Add the TAB staves of `spec` to `mei`, re-finger its `refret` staves and retarget hidden staves' control events.
|
|
55
|
+
* `memory` (optional) keeps fingerings by note ID across calls: a remembered note is fixed for the solver and new
|
|
56
|
+
* results are added to it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function injectTab(mei: string, spec: TabSpec, memory?: FretMemory): string;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* makes the engraving view (breaks, hidden staves, chord symbols) inside the worker.
|
|
9
9
|
*/
|
|
10
10
|
import type { SpellingSpec } from './mei-spelling';
|
|
11
|
+
import type { TabSpec } from './mei-tab';
|
|
11
12
|
/** An attribute's raw (still escaped) value from a tag's attribute text; IDs, numbers and staff lists need no unescaping. */
|
|
12
13
|
export declare function attributeOf(attributes: string, name: string): string | null;
|
|
13
14
|
export type Visitor = (tag: {
|
|
@@ -52,12 +53,19 @@ export type ViewSpec = {
|
|
|
52
53
|
hiddenStaves: string[];
|
|
53
54
|
/** Keep `<harm>` chord symbols. */
|
|
54
55
|
chordSymbols: boolean;
|
|
56
|
+
/** Chord symbol text size in percent (the reader's annotation size); omitted or 100 leaves `<harm>` as encoded. */
|
|
57
|
+
harmSize?: number;
|
|
55
58
|
/**
|
|
56
59
|
* Transposition, key flip and spelling (mei-spelling.ts), applied to the baseline before the view is built. The
|
|
57
60
|
* worker transposes with Verovio's `transpose` / `transposeToSoundingPitch` and respells; the view itself is then
|
|
58
61
|
* loaded untransposed.
|
|
59
62
|
*/
|
|
60
63
|
spelling?: SpellingSpec;
|
|
64
|
+
/**
|
|
65
|
+
* Guitar TAB staves to add after spelling (notation/mei-tab.ts), and staff-bound text to move onto them. Hidden
|
|
66
|
+
* notation staves (TAB view) and unused imported TAB staves are in `hiddenStaves`.
|
|
67
|
+
*/
|
|
68
|
+
tab?: TabSpec;
|
|
61
69
|
};
|
|
62
70
|
/**
|
|
63
71
|
* The reader's engraving view of a baseline: no header, labels or encoded breaks; a page break every `breakEvery`
|
|
@@ -104,7 +104,10 @@ export type BaseTimelineOptions = {
|
|
|
104
104
|
roadmap?: Roadmap;
|
|
105
105
|
/** Note marks and pedals already read from the source (for example by the import worker). */
|
|
106
106
|
marks?: PlaybackMarks;
|
|
107
|
-
/**
|
|
107
|
+
/**
|
|
108
|
+
* Parts to perform; all parts of the score by default. Tempo, fermatas and dynamics always come from the whole score.
|
|
109
|
+
* A TAB staff that doubles a notation part (`tabOf`) is never performed, so the instrument sounds once.
|
|
110
|
+
*/
|
|
108
111
|
parts?: Part[];
|
|
109
112
|
};
|
|
110
113
|
/** Build the BPM-independent performance of `full` (see BaseTimeline). */
|
package/dist/lib/prefs.d.ts
CHANGED
|
@@ -1,9 +1,44 @@
|
|
|
1
1
|
import type { FileSettings } from './file-state';
|
|
2
|
+
import type { TabView } from './tab/tab-parts';
|
|
3
|
+
import type { RangeLevel, SwitchInstrumentId } from './instrument-model';
|
|
4
|
+
export declare const MIN_BPM = 30, MAX_BPM = 240;
|
|
5
|
+
/** The reader's BPM control range; saved and source tempos outside it are clamped. */
|
|
6
|
+
export declare const clampBpm: (bpm: number) => number;
|
|
7
|
+
export declare const TAB_VIEW_NAMES: readonly TabView[];
|
|
8
|
+
/** Standard guitar tuning EADGBE as open-string MIDI, low to high (tab/fret-assign.ts STANDARD_TUNING). */
|
|
9
|
+
export declare const STANDARD_TAB_TUNING: readonly number[];
|
|
10
|
+
export declare const MAX_CAPO = 12;
|
|
11
|
+
export declare const validTabView: (view: unknown) => view is TabView;
|
|
12
|
+
export declare const MIN_TAB_STRINGS = 4, MAX_TAB_STRINGS = 8;
|
|
13
|
+
/** A usable TAB tuning: 4 to 8 open strings (bass to extended-range guitar), MIDI 0-127. */
|
|
14
|
+
export declare const validTabTuning: (tuning: unknown) => tuning is number[];
|
|
15
|
+
export declare const validCapo: (capo: unknown) => capo is number;
|
|
16
|
+
/** A capo as a whole fret 0-12 (fractions round; anything not a number is no capo). */
|
|
17
|
+
export declare const clampCapo: (capo: unknown) => number;
|
|
2
18
|
/** Explicit bars per line (`barsPerLine`) range; Auto is capped separately (render.ts AUTO_BAR_CAP). */
|
|
3
19
|
export declare const BARS_PER_LINE_MIN = 1;
|
|
4
20
|
export declare const BARS_PER_LINE_MAX = 8;
|
|
5
21
|
/** Round and clamp an explicit bar count into range. */
|
|
6
22
|
export declare const clampBarsPerLine: (value: number) => number;
|
|
23
|
+
/** Text add-on size steps, smallest first. `rg` (regular) is the default and draws today's size. */
|
|
24
|
+
export declare const ANNOTATION_SIZES: readonly ["xs", "sm", "md", "rg", "lg", "xl"];
|
|
25
|
+
export type AnnotationSize = typeof ANNOTATION_SIZES[number];
|
|
26
|
+
/** Font scale of each step relative to `rg`; lanes, offsets and bar widths scale with it (render.ts). */
|
|
27
|
+
export declare const ANNOTATION_SCALE: Record<AnnotationSize, number>;
|
|
28
|
+
export declare const isAnnotationSize: (value: unknown) => value is AnnotationSize;
|
|
29
|
+
/** The text add-ons that take a size (`settings.annotationSizes` keys); inferred chord symbols use `chordSymbols`. */
|
|
30
|
+
export type AnnotationKey = 'noteNames' | 'chordSymbols' | 'beatCounts' | 'subdivisions';
|
|
31
|
+
/** The `Prefs` / `FileSettings` key holding each add-on's size. */
|
|
32
|
+
export declare const ANNOTATION_SIZE_PREFS: {
|
|
33
|
+
readonly noteNames: "namesSize";
|
|
34
|
+
readonly chordSymbols: "chordSymbolsSize";
|
|
35
|
+
readonly beatCounts: "countsSize";
|
|
36
|
+
readonly subdivisions: "subdivisionsSize";
|
|
37
|
+
};
|
|
38
|
+
export type AnnotationSizePref = typeof ANNOTATION_SIZE_PREFS[AnnotationKey];
|
|
39
|
+
export declare const ANNOTATION_SIZE_PREF_KEYS: AnnotationSizePref[];
|
|
40
|
+
/** Host sizes per add-on (`settings.annotationSizes`); omitted add-ons keep their current size. */
|
|
41
|
+
export type PepperScoreAnnotationSizes = Partial<Record<AnnotationKey, AnnotationSize>>;
|
|
7
42
|
/** Reader settings; `zoom` is the score's explicit stave scale, or null for the device default (see stave-scale.ts). */
|
|
8
43
|
export type Prefs = FileSettings & {
|
|
9
44
|
zoom: number | null;
|
|
@@ -27,6 +62,38 @@ export type PepperScoreSettings = Partial<{
|
|
|
27
62
|
semitones: number;
|
|
28
63
|
concert: boolean;
|
|
29
64
|
overlap: number;
|
|
65
|
+
/**
|
|
66
|
+
* Text size of each add-on: `'xs' | 'sm' | 'md' | 'rg' | 'lg' | 'xl'` (`'rg'`, regular, is the default). Keys:
|
|
67
|
+
* `noteNames`, `chordSymbols` (source and inferred), `beatCounts` (on-beat counts) and `subdivisions` (the e/&/a
|
|
68
|
+
* counts between beats). Only the add-ons given are applied; unknown sizes are ignored.
|
|
69
|
+
*/
|
|
70
|
+
annotationSizes: PepperScoreAnnotationSizes;
|
|
71
|
+
/** Which staves guitar parts show: `'notation'` (default), `'tab'` or `'both'`. */
|
|
72
|
+
tabView: TabView;
|
|
73
|
+
/** Open-string MIDI pitches of generated TAB, low to high (default EADGBE, [40, 45, 50, 55, 59, 64]). */
|
|
74
|
+
tabTuning: number[];
|
|
75
|
+
/** Capo fret 0-12 of generated TAB; frets are relative to it. */
|
|
76
|
+
capo: number;
|
|
77
|
+
/** Initial tempo, 30-240 BPM (a score's own tempo otherwise). */
|
|
78
|
+
bpm: number;
|
|
79
|
+
/** Spell a transposed view in the enharmonic key (F# major shown as Gb major). */
|
|
80
|
+
keyFlip: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Show the first switchable part (every staff of a grand staff) as this instrument: its sound, clef, written pitch
|
|
83
|
+
* and range. Applied when the score has no saved record, like the other settings.
|
|
84
|
+
*/
|
|
85
|
+
instrument: SwitchInstrumentId;
|
|
86
|
+
/**
|
|
87
|
+
* Instruments per part; wins over `instrument`. A key is either the 1-based source part number as a string
|
|
88
|
+
* (`{ '2': 'trumpet' }`: score parts in order, a grand staff counted once, a drum kit counted too; `onReady`'s
|
|
89
|
+
* `parts[].sourcePart`) or an `onReady` part id (`parts[].id`; a staff of a grand staff switches its whole part).
|
|
90
|
+
* Keys of parts that cannot be switched (`parts[].switchable` false) are ignored.
|
|
91
|
+
*/
|
|
92
|
+
instruments: Record<string, SwitchInstrumentId>;
|
|
93
|
+
/** Range level the switched parts are fitted to: `'beginner'`, `'intermediate'` (default) or `'advanced'`. */
|
|
94
|
+
rangeLevel: RangeLevel;
|
|
95
|
+
/** Move phrases outside the instrument's range by an octave (default `true`). */
|
|
96
|
+
autoRange: boolean;
|
|
30
97
|
}>;
|
|
31
98
|
export declare function settingsToPrefs(settings?: PepperScoreSettings): Partial<Prefs>;
|
|
32
99
|
export declare const viewToMode: (view: "vertical" | "endless") => Prefs["mode"];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type Shift = 0 | 12 | -12;
|
|
2
|
+
/** One event (note or chord): its notes' judged MIDI (sounding plus interval). */
|
|
3
|
+
export type FitEvent = {
|
|
4
|
+
id: string;
|
|
5
|
+
midi: number[];
|
|
6
|
+
};
|
|
7
|
+
/** Merges runs of event ids that a tie links (`[from, to]`), keeping the first run's position. */
|
|
8
|
+
export declare function joinRuns(runs: string[][], ties: [string, string][]): string[][];
|
|
9
|
+
/** The ordered chain of events the ties link around `id` (itself alone when untied), in `order` (event order) when given, else by first appearance in the ties. */
|
|
10
|
+
export declare function tieChainOf(ties: [string, string][], order?: string[]): (id: string) => string[];
|
|
11
|
+
export type ShiftPlan = {
|
|
12
|
+
shifts: Record<string, Shift>;
|
|
13
|
+
bothWays: string[][];
|
|
14
|
+
stillOut: string[][];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Plans an octave per phrase: any note below the range moves every event up, above moves it down, both
|
|
18
|
+
* leaves the phrase (listed in `bothWays`); a phrase still out after its move keeps it (listed in
|
|
19
|
+
* `stillOut`). A chord is out when any of its notes is. No range or `autoRange` off plans no shifts.
|
|
20
|
+
*/
|
|
21
|
+
export declare function planShifts(phrases: FitEvent[][], range: {
|
|
22
|
+
low: number;
|
|
23
|
+
high: number;
|
|
24
|
+
} | undefined, autoRange: boolean): ShiftPlan;
|
|
25
|
+
/** Sets single events from the user's overrides, each extended along its tie chain (the first override on a chain wins); overrides beat planned shifts. */
|
|
26
|
+
export declare function applyOverrides(shifts: Record<string, Shift>, overrides: Record<string, Shift>, chainOf: (id: string) => string[]): Record<string, Shift>;
|
package/dist/lib/render.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { Score } from './score';
|
|
1
|
+
import type { Part, Score, ScoreNote } from './score';
|
|
2
2
|
import type { BaselineInfo } from './notation/mei-view';
|
|
3
|
+
import { type TabView } from './tab/tab-parts';
|
|
3
4
|
export type NotePoint = {
|
|
4
5
|
id: string;
|
|
5
6
|
measure: number;
|
|
@@ -87,6 +88,24 @@ export type RenderOptions = {
|
|
|
87
88
|
fitFloor?: number;
|
|
88
89
|
/** Draw the system holding this Score measure before resolving (a zoom anchor), besides those in view. */
|
|
89
90
|
focusMeasure?: number;
|
|
91
|
+
/**
|
|
92
|
+
* Font scale of each text add-on (1, the default, is the regular size; prefs.ts ANNOTATION_SCALE). Lane rows, label
|
|
93
|
+
* offsets and the room kept above the staff grow with it (bar layout and stave scale do not); source chord symbols are scaled
|
|
94
|
+
* by Verovio (MEI `<rend fontsize>`), so it spaces them itself.
|
|
95
|
+
*/
|
|
96
|
+
annotationScale?: AnnotationScale;
|
|
97
|
+
/** Guitar TAB (docs/specs/guitar-tab.md): which staves guitar parts show, and the tuning and capo of generated TAB. */
|
|
98
|
+
tab?: {
|
|
99
|
+
view: TabView;
|
|
100
|
+
tuning?: number[];
|
|
101
|
+
capo?: number;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
export type AnnotationScale = {
|
|
105
|
+
names?: number;
|
|
106
|
+
chordSymbols?: number;
|
|
107
|
+
counts?: number;
|
|
108
|
+
subdivisions?: number;
|
|
90
109
|
};
|
|
91
110
|
/**
|
|
92
111
|
* Scores up to this many staff-measures (visible staves x measures) draw every system before the first paint, as
|
|
@@ -124,6 +143,22 @@ export declare function staffNumbers(info: BaselineInfo, score: Score): {
|
|
|
124
143
|
byPart: Map<string, string>;
|
|
125
144
|
engraved: string[];
|
|
126
145
|
};
|
|
146
|
+
/**
|
|
147
|
+
* The staves a view engraves: Score parts to staff numbers, the visible parts (a TAB staff that doubles a notation
|
|
148
|
+
* part is never a part of its own: it shows with its partner), the staves to hide, the spelling plan and the guitar
|
|
149
|
+
* TAB plan (tab/tab-parts.ts). Shared with validation/tab-harness.ts.
|
|
150
|
+
*/
|
|
151
|
+
export declare function planStaves(info: BaselineInfo, score: Score, hiddenIds: ReadonlySet<string>, tab?: RenderOptions['tab']): {
|
|
152
|
+
staffOf: Map<string, string>;
|
|
153
|
+
visibleParts: Part[];
|
|
154
|
+
hiddenStaves: string[];
|
|
155
|
+
spelling: import("./notation/mei-spelling").SpellingSpec;
|
|
156
|
+
tabView: TabView;
|
|
157
|
+
tabPlan: import("./tab/tab-parts").TabPlan;
|
|
158
|
+
tabStaves: Set<string>;
|
|
159
|
+
staffCount: number;
|
|
160
|
+
tabAlias: Map<string, ScoreNote>;
|
|
161
|
+
};
|
|
127
162
|
/**
|
|
128
163
|
* Render from the original engraving document through the locally bundled WASM worker.
|
|
129
164
|
*
|
package/dist/lib/score.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SourceDocument } from './notation/document';
|
|
2
|
+
import type { InstrumentId as ModelInstrumentId } from './instrument-model';
|
|
2
3
|
export type Pitch = {
|
|
3
4
|
step: string;
|
|
4
5
|
octave: number;
|
|
@@ -112,6 +113,8 @@ export type Measure = {
|
|
|
112
113
|
};
|
|
113
114
|
export type Part = {
|
|
114
115
|
id: string;
|
|
116
|
+
/** The MusicXML <score-part id> every staff of one part shares; absent for ABC/MIDI single parts (use `id`). */
|
|
117
|
+
sourcePartId?: string;
|
|
115
118
|
name: string;
|
|
116
119
|
clef: string;
|
|
117
120
|
key?: number;
|
|
@@ -122,6 +125,18 @@ export type Part = {
|
|
|
122
125
|
pitchBasis?: 'written' | 'concert';
|
|
123
126
|
transposition?: Transposition;
|
|
124
127
|
measures: Measure[];
|
|
128
|
+
/** A tablature staff (MusicXML clef sign TAB), imported by Verovio as a `tab.guitar` staff. */
|
|
129
|
+
tab?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* The instrument the part was imported as, kept when a reader's Sound pick (or a saved one) replaces `instrument`
|
|
132
|
+
* with the sound's icon id. What the instrument switch offers keys on it (instrument-view.ts `switchablePart`).
|
|
133
|
+
*/
|
|
134
|
+
importedInstrument?: InstrumentId;
|
|
135
|
+
/**
|
|
136
|
+
* The part this TAB staff doubles (its notation staff). A doubling TAB part is engraved but never performed, has no
|
|
137
|
+
* annotation lanes and is not listed in part controls, so the instrument shows and plays once (lib/tab/tab-parts.ts).
|
|
138
|
+
*/
|
|
139
|
+
tabOf?: string;
|
|
125
140
|
};
|
|
126
141
|
export type Score = {
|
|
127
142
|
title: string;
|
|
@@ -137,9 +152,16 @@ export type Score = {
|
|
|
137
152
|
parts: Part[];
|
|
138
153
|
/** Set on a transposed or flipped view of a score (transpose.ts `scoreForView`). */
|
|
139
154
|
pitchView?: import('./transpose').PitchView;
|
|
155
|
+
/**
|
|
156
|
+
* Set on an instrument-switched view (instrument-view.ts `applyInstrumentView`): what the MEI pass needs of its
|
|
157
|
+
* switched and octave-moved staves, by part id. Dropped by `scoreForView` whenever it moves pitches.
|
|
158
|
+
*/
|
|
159
|
+
instrumentView?: {
|
|
160
|
+
staves: Record<string, import('./instrument-view').EngravedSwitch>;
|
|
161
|
+
};
|
|
140
162
|
document?: SourceDocument;
|
|
141
163
|
};
|
|
142
|
-
export type InstrumentId =
|
|
164
|
+
export type InstrumentId = ModelInstrumentId;
|
|
143
165
|
export declare const GM_FAMILIES: readonly ["Keyboard", "Guitar", "Voice", "Percussion", "Drums", "Woodwinds", "Brass", "Strings", "FX / Other"];
|
|
144
166
|
export type GmFamily = typeof GM_FAMILIES[number];
|
|
145
167
|
export type GmSound = {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { SoundPlan } from './sounds';
|
|
2
|
+
/** One sound source's player (public through pepperscore/audio). */
|
|
2
3
|
export type AudioPlayer = {
|
|
3
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Play MIDI `note` at `time` (AudioContext seconds) for `duration` seconds at `velocity` (0-127). Returns a function
|
|
6
|
+
* that stops (or, if it has not started yet, cancels) that one note.
|
|
7
|
+
*/
|
|
4
8
|
start(options: {
|
|
5
9
|
note: number;
|
|
6
10
|
time: number;
|
|
@@ -8,9 +12,13 @@ export type AudioPlayer = {
|
|
|
8
12
|
velocity: number;
|
|
9
13
|
destination?: AudioNode;
|
|
10
14
|
}): () => void;
|
|
15
|
+
/** Stop every sounding note and cancel every scheduled one. */
|
|
11
16
|
stop(): void;
|
|
17
|
+
/** Stop and release the player's buffers and nodes. */
|
|
12
18
|
dispose(): void;
|
|
19
|
+
/** Load (decode) these notes before they are started. */
|
|
13
20
|
loadNotes?(notes: number[]): Promise<void>;
|
|
21
|
+
/** Whether the player has a sound for this note. */
|
|
14
22
|
covers?(note: number): boolean;
|
|
15
23
|
};
|
|
16
24
|
/** The players for one plan (sf2 players are bound to `destination`, a part's track gain). */
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare const STANDARD_TUNING: number[];
|
|
2
|
+
export interface FretPos {
|
|
3
|
+
string: number;
|
|
4
|
+
fret: number;
|
|
5
|
+
}
|
|
6
|
+
/** A fixed fingering, or a string only (a circled string number: the solver picks the fret on that string). */
|
|
7
|
+
export interface FretFixed {
|
|
8
|
+
string: number;
|
|
9
|
+
fret?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface FretEvent {
|
|
12
|
+
onset: number;
|
|
13
|
+
durations: number[];
|
|
14
|
+
pitches: number[];
|
|
15
|
+
fixed?: (FretFixed | undefined)[];
|
|
16
|
+
}
|
|
17
|
+
export interface FretOptions {
|
|
18
|
+
tuning?: number[];
|
|
19
|
+
capo?: number;
|
|
20
|
+
maxFret?: number;
|
|
21
|
+
octaveFold?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export type FretResult = (FretPos & {
|
|
24
|
+
shifted?: number;
|
|
25
|
+
}) | {
|
|
26
|
+
unplayable: true;
|
|
27
|
+
};
|
|
28
|
+
export declare function assignFrets(events: FretEvent[], options?: FretOptions): FretResult[][];
|
|
29
|
+
/** One written note of a staff (any voice or layer): onset and duration in quarter notes, sounding MIDI pitch. */
|
|
30
|
+
export interface FretNote {
|
|
31
|
+
onset: number;
|
|
32
|
+
duration: number;
|
|
33
|
+
pitch: number | null;
|
|
34
|
+
tieStart?: boolean;
|
|
35
|
+
tieStop?: boolean;
|
|
36
|
+
fixed?: FretFixed;
|
|
37
|
+
}
|
|
38
|
+
/** Per written note: its fingering (a tie continuation gets the fingering of the note it continues). */
|
|
39
|
+
export interface FretNoteResult {
|
|
40
|
+
result?: FretResult;
|
|
41
|
+
continuation: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Finger the notes of one staff, every voice together. Shared by the reader (mei-tab.ts) and the bake
|
|
45
|
+
* (scripts/tab-bake.mjs) so both give the same fingerings for the same notes.
|
|
46
|
+
* - Notes starting together are one event, whatever their voice: they sound at once, so they need different strings.
|
|
47
|
+
* - A unison (the same pitch starting together in two voices) is one string: one solver note, ringing as long as the
|
|
48
|
+
* longest of them (ties included); every written note of it gets that fingering.
|
|
49
|
+
* - A tie continuation (`tieStop` with a tie open on its pitch) is not fingered again: it extends the note it continues
|
|
50
|
+
* and takes its fingering. With nothing open (a chunk starting mid-tie) it is fingered as a note.
|
|
51
|
+
* - Notes without a pitch get no result. The input order only breaks ties between equal onsets.
|
|
52
|
+
*/
|
|
53
|
+
export declare function assignNoteFrets(notes: FretNote[], options?: FretOptions): FretNoteResult[];
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which staves show guitar TAB (docs/specs/guitar-tab.md, "Which staves get TAB"). Main-thread only: the reader
|
|
3
|
+
* decides from its Score which notation staves get a generated TAB staff, which imported TAB staves show, and what is
|
|
4
|
+
* hidden; the Verovio worker then injects the TAB staves (notation/mei-tab.ts).
|
|
5
|
+
*/
|
|
6
|
+
import type { Measure, Part, Score, ScoreNote } from '../score';
|
|
7
|
+
import type { TabSpec } from '../notation/mei-tab';
|
|
8
|
+
import type { PartState } from '../file-state';
|
|
9
|
+
export type TabView = 'notation' | 'tab' | 'both';
|
|
10
|
+
/** A generated TAB staff's number: 100 + its notation staff's number. */
|
|
11
|
+
export declare const tabStaffNumber: (n: string) => string;
|
|
12
|
+
/** A note's onset and sounding pitches as one key (`measure:start:midis`, or `r` for a rest). */
|
|
13
|
+
export declare const soundingKeyOf: (part: Part, measure: Measure, note: ScoreNote) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Flag TAB parts (`tab`) and link each to the notation part it doubles (`tabOf`): a sibling staff of the same
|
|
16
|
+
* MusicXML part, or else the nearest pitched part before it with (nearly) the same notes. A TAB part that doubles
|
|
17
|
+
* nothing (a TAB-only score) stays a normal, performed part. Mutates and returns `score`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function linkTabParts(score: Score): Score;
|
|
20
|
+
/** A guitar part: GM programs 25-32 (1-based; nylon to guitar harmonics), the guitar sound, or "guitar" in its name. */
|
|
21
|
+
export declare const isGuitarPart: (part: Part) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Notation parts that take TAB: every guitar part (and every part an imported TAB doubles), else the first pitched
|
|
24
|
+
* part. A part switched to another instrument (instrument-view.ts) takes TAB only if its new instrument is a guitar
|
|
25
|
+
* (its name and its imported TAB no longer count).
|
|
26
|
+
*/
|
|
27
|
+
export declare function tabParts(score: Score): Part[];
|
|
28
|
+
/** Whether the Notation / TAB / Both switch has anything to switch. */
|
|
29
|
+
export declare const canShowTab: (score: Score) => boolean;
|
|
30
|
+
export type TabPlan = {
|
|
31
|
+
/** For the worker; absent when nothing is injected or retargeted. */
|
|
32
|
+
spec?: TabSpec;
|
|
33
|
+
/** Staff numbers hidden by the view (notation staves in TAB view, imported TAB staves when unused). */
|
|
34
|
+
hidden: string[];
|
|
35
|
+
/** Staff numbers the view adds or shows that are not in the baseline's staffDefs (generated TAB staves). */
|
|
36
|
+
added: string[];
|
|
37
|
+
/** The staff a notation part is read from in this view (its TAB staff in TAB view); defaults to its own. */
|
|
38
|
+
display: Map<string, string>;
|
|
39
|
+
/** Imported TAB part shown for a notation part (highlights map the notation part's notes onto it). */
|
|
40
|
+
importedFor: Map<string, Part>;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The reader parts a saved record hides (`parts`: saved part states by ID). Only parts the reader lists can be hidden:
|
|
44
|
+
* a TAB part that doubles a guitar never is (an older reader listed it), and a guitar whose notation was hidden while
|
|
45
|
+
* its TAB part showed stays shown (the guitar was being read from its TAB).
|
|
46
|
+
*/
|
|
47
|
+
export declare function hiddenReaderParts(score: Score, parts: Record<string, PartState | undefined>): string[];
|
|
48
|
+
/**
|
|
49
|
+
* Plan a view: `staffOf` maps parts to baseline staff numbers, `hiddenIds` are parts the reader hid, `stale` is true
|
|
50
|
+
* when the view moves sounding pitches (transposition: imported `tab.fret`s no longer match, so imported TAB is replaced
|
|
51
|
+
* by generated TAB and a TAB-only staff is re-fingered). A concert view moves written notes to the pitches they already
|
|
52
|
+
* sound, so it never makes TAB stale. A part of the Score's instrument view (switched or octave-moved,
|
|
53
|
+
* `score.instrumentView`) makes its own TAB stale: generated (its fingerings not fixed) while it is a guitar, else
|
|
54
|
+
* none (it is no longer a TAB part, and its imported TAB staff is hidden). `sounding` lists staves whose spelled notes are at sounding pitch (their
|
|
55
|
+
* `trans.semi` no longer applies).
|
|
56
|
+
*/
|
|
57
|
+
export declare function planTab(score: Score, staffOf: Map<string, string>, view: TabView, options: {
|
|
58
|
+
tuning: number[];
|
|
59
|
+
capo: number;
|
|
60
|
+
stale: boolean;
|
|
61
|
+
semitones?: number;
|
|
62
|
+
sounding?: string[];
|
|
63
|
+
hiddenIds?: Set<string>;
|
|
64
|
+
}): TabPlan;
|
package/dist/lib/transpose.d.ts
CHANGED
|
@@ -28,8 +28,9 @@ export declare function viewProfile(part: Part, view: ScorePitchView): SpellingP
|
|
|
28
28
|
*/
|
|
29
29
|
export declare function scoreForView(score: Score, view: ScorePitchView, semitones: number, flip?: boolean): Score;
|
|
30
30
|
/**
|
|
31
|
-
* The worker's spelling plan for a Score view (`scoreForView`'s result
|
|
32
|
-
* flip, per-staff profiles and moved staves,
|
|
31
|
+
* The worker's spelling plan for a Score view (`scoreForView`'s result, optionally instrument-switched by
|
|
32
|
+
* `applyInstrumentView`) with its staff numbers: the same interval, flip, per-staff profiles and moved staves, which
|
|
33
|
+
* staves are percussion (never given a key signature), and the switched staves' shift, clef and octave moves.
|
|
33
34
|
*/
|
|
34
35
|
export declare function spellingSpecFor(score: Score, staffOf: Map<string, string>): SpellingSpec;
|
|
35
36
|
/** The key of a measure in a (view) Score, for app-side pitch text such as inferred chord symbols. */
|
|
@@ -50,6 +50,21 @@ export type VerovioRequest = {
|
|
|
50
50
|
chunkBudget: number;
|
|
51
51
|
simulateOom?: boolean;
|
|
52
52
|
});
|
|
53
|
+
/**
|
|
54
|
+
* Where the worker imports Verovio from: upstream's own, unmodified ES modules, loaded at runtime so they stay a
|
|
55
|
+
* separately replaceable library (LGPL-3.0-or-later). `module` is the Emscripten module (npm verovio's
|
|
56
|
+
* dist/verovio-module.mjs, default export: an async factory of the WASM module); `toolkit` is the JavaScript toolkit
|
|
57
|
+
* (dist/verovio.mjs, exports `VerovioToolkit` and `enableLogToBuffer`). Absolute URLs.
|
|
58
|
+
*/
|
|
59
|
+
export type VerovioFiles = {
|
|
60
|
+
module: string;
|
|
61
|
+
toolkit: string;
|
|
62
|
+
};
|
|
63
|
+
/** Sent once by the runtime right after it starts a worker, before any request. */
|
|
64
|
+
export type VerovioConfigure = {
|
|
65
|
+
kind: 'configure';
|
|
66
|
+
files: VerovioFiles;
|
|
67
|
+
};
|
|
53
68
|
export type VerovioReply = {
|
|
54
69
|
id: number;
|
|
55
70
|
value?: unknown;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SourceDocument } from './notation/document';
|
|
2
|
-
import type { BaselineInfo, PagesResult, ProbeResult, VerovioReply, ViewSpec } from './verovio-protocol';
|
|
2
|
+
import type { BaselineInfo, PagesResult, ProbeResult, VerovioFiles, VerovioReply, ViewSpec } from './verovio-protocol';
|
|
3
3
|
/** A worker failure; `code` says why (see VerovioReply). */
|
|
4
4
|
export declare class VerovioError extends Error {
|
|
5
5
|
readonly code?: VerovioReply['code'];
|
|
@@ -24,6 +24,14 @@ export declare const chunkSettings: () => {
|
|
|
24
24
|
* threshold) on a fresh worker. The caller then opens or draws the score again. Returns the new budget.
|
|
25
25
|
*/
|
|
26
26
|
export declare function reduceChunkSize(): number;
|
|
27
|
+
/** The Verovio files under a directory laid out like the verovio npm package's dist/; a relative URL resolves against the page. */
|
|
28
|
+
export declare function verovioFilesAt(base: string, page?: string): VerovioFiles;
|
|
29
|
+
/**
|
|
30
|
+
* Load Verovio from `base` (see PepperScoreProps.verovioBaseUrl) instead of the shipped copy. Every reader on the page
|
|
31
|
+
* shares one worker, so this applies to all of them, from the next time the worker starts (the first engraving, or
|
|
32
|
+
* a restart); a blank `base` changes nothing.
|
|
33
|
+
*/
|
|
34
|
+
export declare function setVerovioBaseUrl(base: string | undefined): void;
|
|
27
35
|
export declare function verovioRevision(document: SourceDocument): number;
|
|
28
36
|
/** A reader mounted: a channel of its own, so its imports and renders never supersede another reader's. */
|
|
29
37
|
export declare function openVerovioChannel(): number;
|