pepperscore 0.1.1 → 0.3.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 +64 -0
- package/LICENSE +26 -12
- package/README.md +128 -9
- package/dist/THIRD_PARTY_NOTICES.txt +1222 -0
- package/dist/assets/{import.worker-D0XfuAHu.js → import.worker-nfqQ5M0Y.js} +2 -2
- package/dist/assets/verovio.worker-DGik-H4a.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/PepperScore.d.ts +111 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2650 -3196
- package/dist/index.js.map +1 -1
- package/dist/lib/chrome.d.ts +5 -2
- package/dist/lib/clock.d.ts +13 -0
- package/dist/lib/file-state.d.ts +17 -4
- package/dist/lib/header-controls.d.ts +7 -3
- package/dist/lib/hit-test.d.ts +18 -0
- package/dist/lib/instruments.d.ts +82 -0
- package/dist/lib/metronome.d.ts +33 -0
- package/dist/lib/notation/mei-tab.d.ts +51 -0
- package/dist/lib/notation/mei-view.d.ts +8 -0
- package/dist/lib/playback/clock-time.d.ts +20 -0
- package/dist/lib/playback/timeline.d.ts +4 -1
- package/dist/lib/prefs.d.ts +50 -0
- package/dist/lib/render.d.ts +36 -1
- package/dist/lib/score.d.ts +7 -0
- 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 +58 -0
- package/dist/lib/verovio-protocol.d.ts +15 -0
- package/dist/lib/verovio-runtime.d.ts +9 -1
- 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 +7 -1
- package/dist/assets/verovio.worker-DkHQmOsT.js +0 -19034
- package/dist/sf2-player-CRlOJDhD.js.map +0 -1
package/dist/lib/chrome.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Chrome presets (docs/specs/pepperscore-embeddable-component.md, "Chrome presets") and per-control overrides. No runtime imports. */
|
|
2
2
|
export type ChromePreset = 'full' | 'minimal' | 'none';
|
|
3
|
-
export type PepperScoreControls = Partial<Record<'mixer' | 'openFile' | 'drawer' | 'transport' | 'viewToggle' | 'zoom', boolean>>;
|
|
3
|
+
export type PepperScoreControls = Partial<Record<'mixer' | 'openFile' | 'drawer' | 'transport' | 'viewToggle' | 'zoom' | 'tabToggle', boolean>>;
|
|
4
4
|
export type ResolvedChrome = {
|
|
5
5
|
header: boolean;
|
|
6
6
|
transport: boolean;
|
|
@@ -9,6 +9,8 @@ export type ResolvedChrome = {
|
|
|
9
9
|
mixer: boolean;
|
|
10
10
|
drawer: boolean;
|
|
11
11
|
zoom: boolean;
|
|
12
|
+
/** The Notation / TAB / Both switch (shown only for a score with a stave that can take TAB). */
|
|
13
|
+
tabToggle: boolean;
|
|
12
14
|
/** The overlaid play/stop button of `minimal`. */
|
|
13
15
|
compactPlay: boolean;
|
|
14
16
|
/** Playhead, note highlight and follow. */
|
|
@@ -21,6 +23,7 @@ export type ResolvedChrome = {
|
|
|
21
23
|
/**
|
|
22
24
|
* `transport` covers stop, play, BPM, transpose, key flip and bars; `viewToggle` the Vertical/Endless toggle; `openFile` the
|
|
23
25
|
* Open button, file input, open dialog and reopen offer; `mixer` the mixer and the part icons / instrument picker / stave
|
|
24
|
-
* eyes; `zoom` the stave-scale slider, pinch zoom and the page arrows row; `drawer` the bottom drawer and its handle
|
|
26
|
+
* eyes; `zoom` the stave-scale slider, pinch zoom and the page arrows row; `drawer` the bottom drawer and its handle;
|
|
27
|
+
* `tabToggle` the Notation / TAB / Both switch (header and drawer).
|
|
25
28
|
*/
|
|
26
29
|
export declare function resolveChrome(preset?: ChromePreset, controls?: PepperScoreControls): ResolvedChrome;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** A host-owned clock that drives the playhead (the `clock` prop). Types only: no runtime imports. */
|
|
2
|
+
export type ClockEvent = {
|
|
3
|
+
type: 'play' | 'pause' | 'seek' | 'rate';
|
|
4
|
+
time: number;
|
|
5
|
+
};
|
|
6
|
+
export type ExternalClock = {
|
|
7
|
+
/** Current time in seconds from the start of the score (score beat 0, the pickup's first beat when there is one). May be negative during a count-in. */
|
|
8
|
+
now(): number;
|
|
9
|
+
/** Whether the clock is running; the playhead updates every animation frame while it is. */
|
|
10
|
+
readonly playing: boolean;
|
|
11
|
+
/** Called on play, pause, seek and rate changes; returns an unsubscribe function. */
|
|
12
|
+
subscribe(listener: (event: ClockEvent) => void): () => void;
|
|
13
|
+
};
|
package/dist/lib/file-state.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type InstrumentId, type Score } from './score';
|
|
2
2
|
import { type DeviceClass } from './stave-scale';
|
|
3
|
+
import { clampBpm, MAX_BPM, MIN_BPM, type AnnotationSize } from './prefs';
|
|
4
|
+
import type { TabView } from './tab/tab-parts';
|
|
3
5
|
export type FileSource = {
|
|
4
6
|
name: string;
|
|
5
7
|
size: number;
|
|
@@ -22,7 +24,20 @@ export type FileSettings = {
|
|
|
22
24
|
scorePitch: 'written' | 'concert';
|
|
23
25
|
/** Spell the transposed view in the enharmonic key (F# major shown as Gb major); optional on read, default false. */
|
|
24
26
|
keyFlip: boolean;
|
|
27
|
+
/** Text add-on sizes (prefs.ts ANNOTATION_SIZES); optional on read, default 'rg' (the size every earlier record showed). */
|
|
28
|
+
namesSize: AnnotationSize;
|
|
29
|
+
chordSymbolsSize: AnnotationSize;
|
|
30
|
+
countsSize: AnnotationSize;
|
|
31
|
+
subdivisionsSize: AnnotationSize;
|
|
32
|
+
/** TAB view, tuning (open-string MIDI, low to high) and capo; always written (see `SavedSettings` for reading). */
|
|
33
|
+
tabView: TabView;
|
|
34
|
+
tabTuning: number[];
|
|
35
|
+
capo: number;
|
|
25
36
|
};
|
|
37
|
+
/** Settings added after version 2 shipped: a record without them (or with unusable ones) leaves the reader's own. */
|
|
38
|
+
export type LateSettingKey = 'tabView' | 'tabTuning' | 'capo';
|
|
39
|
+
/** Settings as read from a saved record. */
|
|
40
|
+
export type SavedSettings = Omit<FileSettings, LateSettingKey> & Partial<Pick<FileSettings, LateSettingKey>>;
|
|
26
41
|
/** Saved view: an absolute stave scale and the device class it was chosen on (see stave-scale.ts). */
|
|
27
42
|
export type ScoreView = {
|
|
28
43
|
zoom: number;
|
|
@@ -40,7 +55,7 @@ export type FileState = {
|
|
|
40
55
|
source: FileSource;
|
|
41
56
|
/** Epoch ms of the last time the score was opened; the store keeps the most recent records. */
|
|
42
57
|
lastOpened: number;
|
|
43
|
-
settings:
|
|
58
|
+
settings: SavedSettings;
|
|
44
59
|
parts: Record<string, PartState>;
|
|
45
60
|
view?: ScoreView;
|
|
46
61
|
};
|
|
@@ -53,9 +68,7 @@ export type FileStateV1 = {
|
|
|
53
68
|
};
|
|
54
69
|
parts: Record<string, PartState>;
|
|
55
70
|
};
|
|
56
|
-
export
|
|
57
|
-
/** The reader's BPM control range; saved and source tempos outside it are clamped. */
|
|
58
|
-
export declare const clampBpm: (bpm: number) => number;
|
|
71
|
+
export { clampBpm, MAX_BPM, MIN_BPM };
|
|
59
72
|
/** The localStorage key of a v1 record; `prefix` is the reader's persist namespace (score-db keyPrefix). */
|
|
60
73
|
export declare const legacyStorageKey: (hash: string, prefix?: string) => string;
|
|
61
74
|
/**
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
* the header; `secondary` controls sit inline above MOBILE_HEADER_BREAKPOINT
|
|
7
7
|
* and move into the "More controls" dropdown at or below it. PepperScore.tsx maps
|
|
8
8
|
* each id to its element; every control is always rendered (`bars` is disabled outside Vertical view, `keyFlip` when the key has no enharmonic) so the
|
|
9
|
-
* header footprint never depends on client-only state.
|
|
9
|
+
* header footprint never depends on client-only state. `tab` (the Notation / TAB / Both switch) is the exception: it shows only for a score with a
|
|
10
|
+
* stave that can take TAB (any pitched part).
|
|
10
11
|
*/
|
|
11
|
-
export type HeaderControlId = 'stop' | 'play' | 'openFile' | 'bpm' | 'transpose' | 'keyFlip' | 'mode' | 'bars' | 'staveScale' | 'mixer';
|
|
12
|
+
export type HeaderControlId = 'stop' | 'play' | 'openFile' | 'bpm' | 'transpose' | 'keyFlip' | 'mode' | 'tab' | 'bars' | 'staveScale' | 'mixer';
|
|
12
13
|
export type HeaderControlTier = 'primary' | 'secondary';
|
|
13
14
|
export type HeaderControlConfig = {
|
|
14
15
|
id: HeaderControlId;
|
|
@@ -26,6 +27,9 @@ export declare const HEADER_CONTROLS: readonly [{
|
|
|
26
27
|
}, {
|
|
27
28
|
readonly id: "mode";
|
|
28
29
|
readonly tier: "primary";
|
|
30
|
+
}, {
|
|
31
|
+
readonly id: "tab";
|
|
32
|
+
readonly tier: "secondary";
|
|
29
33
|
}, {
|
|
30
34
|
readonly id: "bpm";
|
|
31
35
|
readonly tier: "secondary";
|
|
@@ -50,4 +54,4 @@ export declare const MOBILE_HEADER_BREAKPOINT = 760;
|
|
|
50
54
|
/** Stave scale (zoom) bounds shared by the header slider and pinch zoom live with the defaults in stave-scale.ts. */
|
|
51
55
|
export { clampStaveScale, STAVE_SCALE_MAX, STAVE_SCALE_MIN, STAVE_SCALE_STEP } from './stave-scale';
|
|
52
56
|
/** Which `controls` key shows each header control (see chrome.ts). */
|
|
53
|
-
export declare const HEADER_CONTROL_GROUP: Record<HeaderControlId, 'transport' | 'viewToggle' | 'openFile' | 'zoom' | 'mixer'>;
|
|
57
|
+
export declare const HEADER_CONTROL_GROUP: Record<HeaderControlId, 'transport' | 'viewToggle' | 'openFile' | 'zoom' | 'mixer' | 'tabToggle'>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Click hit testing over the drawn notes (pure: the boxes are measured by the caller, in client px). */
|
|
2
|
+
export type HitRect = {
|
|
3
|
+
left: number;
|
|
4
|
+
top: number;
|
|
5
|
+
right: number;
|
|
6
|
+
bottom: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
};
|
|
10
|
+
/** A drawn note or rest: its whole box (stem, flag, accidentals, dots, lyrics) and its notehead boxes (a rest: its glyph). */
|
|
11
|
+
export type DrawnNote = {
|
|
12
|
+
box: HitRect;
|
|
13
|
+
heads: HitRect[];
|
|
14
|
+
};
|
|
15
|
+
/** The note nearest (x, y): the notehead centre nearest in x, stacked noteheads split by the nearest in y. */
|
|
16
|
+
export declare function nearestNote<T extends DrawnNote>(items: T[], x: number, y: number): T | undefined;
|
|
17
|
+
/** The note whose drawn box (grown by `slop` px) holds (x, y); overlapping boxes go to the nearest notehead. */
|
|
18
|
+
export declare function noteInBox<T extends DrawnNote>(items: T[], x: number, y: number, slop: number): T | undefined;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type SoundPackName } from './assets';
|
|
2
|
+
import { type AudioPlayer } from './sound-players';
|
|
3
|
+
import { type SoundPlan, type SoundRequest, type SoundSource } from './sounds';
|
|
4
|
+
import { type MetronomeVoice } from './metronome';
|
|
5
|
+
export type InstrumentOptions = {
|
|
6
|
+
/** Root of a pepperscore-sounds-<pack> layout (relative to the page); default: the jsDelivr copy of pepperscore-sounds-<soundPack>. */
|
|
7
|
+
assetBaseUrl?: string;
|
|
8
|
+
/** Picks the default assetBaseUrl. With your own assetBaseUrl, its pack.json decides which FluidR3 sounds exist. */
|
|
9
|
+
soundPack?: SoundPackName;
|
|
10
|
+
/** Your own sounds, claimed per GM program or for the drum kit (the PepperScore `soundSources` prop). */
|
|
11
|
+
sources?: readonly SoundSource[];
|
|
12
|
+
/** Default: the page's shared AudioContext (getSharedAudio). */
|
|
13
|
+
context?: AudioContext;
|
|
14
|
+
/** Where the instrument's output goes. Default: the shared master compressor (or `context.destination` for your own context). */
|
|
15
|
+
destination?: AudioNode;
|
|
16
|
+
/** Notes to load before the promise resolves. Default: 21-108 for an instrument, none for the drum kit. */
|
|
17
|
+
notes?: number[];
|
|
18
|
+
};
|
|
19
|
+
/** The public view of an instrument's sound plan. */
|
|
20
|
+
export type InstrumentPlan = {
|
|
21
|
+
readonly kind: SoundPlan['kind'];
|
|
22
|
+
readonly sourceId: string;
|
|
23
|
+
};
|
|
24
|
+
/** A loaded sound: an AudioPlayer plus its output gain (volume) and the plan it came from. */
|
|
25
|
+
export type Instrument = AudioPlayer & {
|
|
26
|
+
readonly context: AudioContext;
|
|
27
|
+
/** The instrument's volume; connected to `destination`. */
|
|
28
|
+
readonly output: GainNode;
|
|
29
|
+
/** Which kind of source plays it and its id (for example `'builtin:fluidr3'`). Read-only; the plan's URLs and presets are internal. */
|
|
30
|
+
readonly plan: InstrumentPlan;
|
|
31
|
+
/** Load (decode) these notes; a note starts silently until it is loaded. Drums load TimGM6mb's kit for notes the kit lacks. */
|
|
32
|
+
loadNotes(notes: number[]): Promise<void>;
|
|
33
|
+
/** Whether a loaded player can sound this note. */
|
|
34
|
+
covers(note: number): boolean;
|
|
35
|
+
};
|
|
36
|
+
/** A GM program (1-128), a FluidR3 sound name (`'acoustic_grand_piano'`), or `'drums'` for the GM drum kit (`'drum-kit'`, the score part id, is accepted as an alias). */
|
|
37
|
+
export type InstrumentName = number | string;
|
|
38
|
+
/** The sound request for a program number, a FluidR3 name or 'drums'/'drum-kit'. */
|
|
39
|
+
export declare function instrumentRequest(sound: InstrumentName): SoundRequest;
|
|
40
|
+
/**
|
|
41
|
+
* Load an instrument through pepperscore's sound resolution. `start()` returns a stop function for that one note;
|
|
42
|
+
* `stop()` stops every sounding note and cancels every scheduled one. A note's `destination` is honoured by sample-pack
|
|
43
|
+
* and note-file sounds; SF2 sounds always play through `output`.
|
|
44
|
+
*/
|
|
45
|
+
export declare function loadInstrument(sound: InstrumentName, options?: InstrumentOptions): Promise<Instrument>;
|
|
46
|
+
/** The GM drum kit (`loadInstrument('drums', options)`): Perfect Drums note files, TimGM6mb's kit for notes they lack. */
|
|
47
|
+
export declare const loadDrumKit: (options?: InstrumentOptions) => Promise<Instrument>;
|
|
48
|
+
export type MetronomeOptions = Omit<InstrumentOptions, 'notes'> & {
|
|
49
|
+
/** Default 'woodblock'. */
|
|
50
|
+
voice?: MetronomeVoice;
|
|
51
|
+
/** Output volume, 0-1. Default 0.5 (gentle). */
|
|
52
|
+
gain?: number;
|
|
53
|
+
};
|
|
54
|
+
export type Metronome = {
|
|
55
|
+
readonly voice: MetronomeVoice;
|
|
56
|
+
readonly output: GainNode;
|
|
57
|
+
/**
|
|
58
|
+
* Schedule one beat at `time` (AudioContext seconds). `beat` counts from 0 within the bar; beat 0 is accented unless
|
|
59
|
+
* `accent` says otherwise. Returns a stop function for that beat.
|
|
60
|
+
*/
|
|
61
|
+
tick(options: {
|
|
62
|
+
time: number;
|
|
63
|
+
beat: number;
|
|
64
|
+
accent?: boolean;
|
|
65
|
+
}): () => void;
|
|
66
|
+
/**
|
|
67
|
+
* Resolves once the drum kit and the notes of the voice given to `createMetronome` have loaded (or failed: then the
|
|
68
|
+
* synthesized sounds keep playing). `createMetronome` itself does not wait for it.
|
|
69
|
+
*/
|
|
70
|
+
readonly ready: Promise<void>;
|
|
71
|
+
/** Switch voice; resolves when the drum kit notes the voice needs have loaded. Until then the voice plays its synthesized sound. A failed load is retried by the next call. */
|
|
72
|
+
setVoice(voice: MetronomeVoice): Promise<void>;
|
|
73
|
+
/** Stop every sounding and scheduled beat. */
|
|
74
|
+
stop(): void;
|
|
75
|
+
dispose(): void;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* A metronome on the shared AudioContext; drum voices come from the same drum kit loadDrumKit plays. Resolves at once:
|
|
79
|
+
* the drum kit (a few MB for the woodblock's TimGM6mb kit) loads in the background, and beats play the synthesized
|
|
80
|
+
* sound until it arrives (`await metronome.ready` to wait).
|
|
81
|
+
*/
|
|
82
|
+
export declare function createMetronome(options?: MetronomeOptions): Promise<Metronome>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a metronome beat sounds like, per voice (public through pepperscore/audio's createMetronome). Pure: no Web Audio
|
|
3
|
+
* and no runtime imports (validation/audio-api.mjs runs it in Node).
|
|
4
|
+
* - woodblock: GM hi wood block (76) on beat 1, low wood block (77) on the others, when the drum kit has them; else a
|
|
5
|
+
* soft synthesized knock.
|
|
6
|
+
* - drum-machine: kick (36) on beat 1, closed hi-hat (42) on the others, from the drum kit.
|
|
7
|
+
* - click: a soft, short synthesized tick.
|
|
8
|
+
* Beat 1 (`beat` 0) is accented: a louder note, or a higher, louder synth sound.
|
|
9
|
+
*/
|
|
10
|
+
export type MetronomeVoice = 'woodblock' | 'drum-machine' | 'click';
|
|
11
|
+
export declare const METRONOME_VOICES: readonly MetronomeVoice[];
|
|
12
|
+
export type MetronomeHit = {
|
|
13
|
+
kind: 'note';
|
|
14
|
+
note: number;
|
|
15
|
+
velocity: number;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'knock' | 'tick';
|
|
18
|
+
accent: boolean;
|
|
19
|
+
};
|
|
20
|
+
export declare const WOODBLOCK_HIGH = 76;
|
|
21
|
+
export declare const WOODBLOCK_LOW = 77;
|
|
22
|
+
export declare const KICK = 36;
|
|
23
|
+
export declare const CLOSED_HAT = 42;
|
|
24
|
+
/** Drum notes a voice plays (loaded up front); the synthesized click needs none. */
|
|
25
|
+
export declare const metronomeNotes: (voice: MetronomeVoice) => number[];
|
|
26
|
+
/**
|
|
27
|
+
* The hits for one beat. `beat` counts from 0 (beat 1 of the bar) and `accent` defaults to `beat === 0`. `kit` says
|
|
28
|
+
* whether the drum kit loaded and which notes it plays; without it, sample voices fall back to synthesized sounds.
|
|
29
|
+
*/
|
|
30
|
+
export declare function metronomeHits(voice: MetronomeVoice, beat: number, { accent, covers }?: {
|
|
31
|
+
accent?: boolean;
|
|
32
|
+
covers?: (note: number) => boolean;
|
|
33
|
+
}): MetronomeHit[];
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
/**
|
|
37
|
+
* Generated staves whose notes are already at sounding pitch (the concert view of a transposing part): their
|
|
38
|
+
* `trans.semi` was applied by spelling and must not be applied again.
|
|
39
|
+
*/
|
|
40
|
+
sounding?: string[];
|
|
41
|
+
/** Imported TAB staves (no notation partner) to re-finger, by staff `@n`: the semitones their pitches move. */
|
|
42
|
+
refret?: Record<string, number>;
|
|
43
|
+
};
|
|
44
|
+
/** Fingerings by notation note `xml:id`, kept across chunk documents so a note keeps its fret wherever it is drawn. */
|
|
45
|
+
export type FretMemory = Map<string, FretPos>;
|
|
46
|
+
/**
|
|
47
|
+
* Add the TAB staves of `spec` to `mei`, re-finger its `refret` staves and retarget hidden staves' control events.
|
|
48
|
+
* `memory` (optional) keeps fingerings by note ID across calls: a remembered note is fixed for the solver and new
|
|
49
|
+
* results are added to it.
|
|
50
|
+
*/
|
|
51
|
+
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`
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PerformanceTimeline } from './timeline';
|
|
2
|
+
export type ClockTimeline = Pick<PerformanceTimeline, 'events' | 'positions' | 'initialBpm'>;
|
|
3
|
+
export type NoteOnset = {
|
|
4
|
+
noteId: string;
|
|
5
|
+
midi: number;
|
|
6
|
+
measureIndex: number;
|
|
7
|
+
occurrence: number;
|
|
8
|
+
seconds: number;
|
|
9
|
+
};
|
|
10
|
+
/** Playback seconds per timeline unit at `bpm`; an invalid BPM plays at the score's opening tempo (same rule as playbackScale). */
|
|
11
|
+
export declare function scoreSecondsScale(timeline: Pick<PerformanceTimeline, 'initialBpm'>, bpm: number): number;
|
|
12
|
+
/**
|
|
13
|
+
* Note onsets in seconds at the score's own tempo map: the times clock mode maps `clock.now()` against. One entry per
|
|
14
|
+
* performed pitch (repeats included), in performed order. Seconds count from score beat 0, a pickup's first beat.
|
|
15
|
+
*/
|
|
16
|
+
export declare function noteOnsetSeconds(timeline: Pick<PerformanceTimeline, 'events' | 'initialBpm'>): NoteOnset[];
|
|
17
|
+
/** Playback seconds (at `bpm`) where a written note sounds, at its performed occurrence nearest `nearSeconds`; null for a rest or unknown note. */
|
|
18
|
+
export declare function noteSeekSeconds(timeline: ClockTimeline, noteId: string, nearSeconds: number, bpm: number): number | null;
|
|
19
|
+
/** Playback seconds (at `bpm`) where a measure's performed occurrence nearest `nearSeconds` starts; null if it is never performed. */
|
|
20
|
+
export declare function measureSeekSeconds(timeline: ClockTimeline, measureIndex: number, nearSeconds: number, bpm: number): number | null;
|
|
@@ -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,43 @@
|
|
|
1
1
|
import type { FileSettings } from './file-state';
|
|
2
|
+
import type { TabView } from './tab/tab-parts';
|
|
3
|
+
export declare const MIN_BPM = 30, MAX_BPM = 240;
|
|
4
|
+
/** The reader's BPM control range; saved and source tempos outside it are clamped. */
|
|
5
|
+
export declare const clampBpm: (bpm: number) => number;
|
|
6
|
+
export declare const TAB_VIEW_NAMES: readonly TabView[];
|
|
7
|
+
/** Standard guitar tuning EADGBE as open-string MIDI, low to high (tab/fret-assign.ts STANDARD_TUNING). */
|
|
8
|
+
export declare const STANDARD_TAB_TUNING: readonly number[];
|
|
9
|
+
export declare const MAX_CAPO = 12;
|
|
10
|
+
export declare const validTabView: (view: unknown) => view is TabView;
|
|
11
|
+
export declare const MIN_TAB_STRINGS = 4, MAX_TAB_STRINGS = 8;
|
|
12
|
+
/** A usable TAB tuning: 4 to 8 open strings (bass to extended-range guitar), MIDI 0-127. */
|
|
13
|
+
export declare const validTabTuning: (tuning: unknown) => tuning is number[];
|
|
14
|
+
export declare const validCapo: (capo: unknown) => capo is number;
|
|
15
|
+
/** A capo as a whole fret 0-12 (fractions round; anything not a number is no capo). */
|
|
16
|
+
export declare const clampCapo: (capo: unknown) => number;
|
|
2
17
|
/** Explicit bars per line (`barsPerLine`) range; Auto is capped separately (render.ts AUTO_BAR_CAP). */
|
|
3
18
|
export declare const BARS_PER_LINE_MIN = 1;
|
|
4
19
|
export declare const BARS_PER_LINE_MAX = 8;
|
|
5
20
|
/** Round and clamp an explicit bar count into range. */
|
|
6
21
|
export declare const clampBarsPerLine: (value: number) => number;
|
|
22
|
+
/** Text add-on size steps, smallest first. `rg` (regular) is the default and draws today's size. */
|
|
23
|
+
export declare const ANNOTATION_SIZES: readonly ["xs", "sm", "md", "rg", "lg", "xl"];
|
|
24
|
+
export type AnnotationSize = typeof ANNOTATION_SIZES[number];
|
|
25
|
+
/** Font scale of each step relative to `rg`; lanes, offsets and bar widths scale with it (render.ts). */
|
|
26
|
+
export declare const ANNOTATION_SCALE: Record<AnnotationSize, number>;
|
|
27
|
+
export declare const isAnnotationSize: (value: unknown) => value is AnnotationSize;
|
|
28
|
+
/** The text add-ons that take a size (`settings.annotationSizes` keys); inferred chord symbols use `chordSymbols`. */
|
|
29
|
+
export type AnnotationKey = 'noteNames' | 'chordSymbols' | 'beatCounts' | 'subdivisions';
|
|
30
|
+
/** The `Prefs` / `FileSettings` key holding each add-on's size. */
|
|
31
|
+
export declare const ANNOTATION_SIZE_PREFS: {
|
|
32
|
+
readonly noteNames: "namesSize";
|
|
33
|
+
readonly chordSymbols: "chordSymbolsSize";
|
|
34
|
+
readonly beatCounts: "countsSize";
|
|
35
|
+
readonly subdivisions: "subdivisionsSize";
|
|
36
|
+
};
|
|
37
|
+
export type AnnotationSizePref = typeof ANNOTATION_SIZE_PREFS[AnnotationKey];
|
|
38
|
+
export declare const ANNOTATION_SIZE_PREF_KEYS: AnnotationSizePref[];
|
|
39
|
+
/** Host sizes per add-on (`settings.annotationSizes`); omitted add-ons keep their current size. */
|
|
40
|
+
export type PepperScoreAnnotationSizes = Partial<Record<AnnotationKey, AnnotationSize>>;
|
|
7
41
|
/** Reader settings; `zoom` is the score's explicit stave scale, or null for the device default (see stave-scale.ts). */
|
|
8
42
|
export type Prefs = FileSettings & {
|
|
9
43
|
zoom: number | null;
|
|
@@ -27,6 +61,22 @@ export type PepperScoreSettings = Partial<{
|
|
|
27
61
|
semitones: number;
|
|
28
62
|
concert: boolean;
|
|
29
63
|
overlap: number;
|
|
64
|
+
/**
|
|
65
|
+
* Text size of each add-on: `'xs' | 'sm' | 'md' | 'rg' | 'lg' | 'xl'` (`'rg'`, regular, is the default). Keys:
|
|
66
|
+
* `noteNames`, `chordSymbols` (source and inferred), `beatCounts` (on-beat counts) and `subdivisions` (the e/&/a
|
|
67
|
+
* counts between beats). Only the add-ons given are applied; unknown sizes are ignored.
|
|
68
|
+
*/
|
|
69
|
+
annotationSizes: PepperScoreAnnotationSizes;
|
|
70
|
+
/** Which staves guitar parts show: `'notation'` (default), `'tab'` or `'both'`. */
|
|
71
|
+
tabView: TabView;
|
|
72
|
+
/** Open-string MIDI pitches of generated TAB, low to high (default EADGBE, [40, 45, 50, 55, 59, 64]). */
|
|
73
|
+
tabTuning: number[];
|
|
74
|
+
/** Capo fret 0-12 of generated TAB; frets are relative to it. */
|
|
75
|
+
capo: number;
|
|
76
|
+
/** Initial tempo, 30-240 BPM (a score's own tempo otherwise). */
|
|
77
|
+
bpm: number;
|
|
78
|
+
/** Spell a transposed view in the enharmonic key (F# major shown as Gb major). */
|
|
79
|
+
keyFlip: boolean;
|
|
30
80
|
}>;
|
|
31
81
|
export declare function settingsToPrefs(settings?: PepperScoreSettings): Partial<Prefs>;
|
|
32
82
|
export declare const viewToMode: (view: "vertical" | "endless") => Prefs["mode"];
|
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
|
@@ -122,6 +122,13 @@ export type Part = {
|
|
|
122
122
|
pitchBasis?: 'written' | 'concert';
|
|
123
123
|
transposition?: Transposition;
|
|
124
124
|
measures: Measure[];
|
|
125
|
+
/** A tablature staff (MusicXML clef sign TAB), imported by Verovio as a `tab.guitar` staff. */
|
|
126
|
+
tab?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* The part this TAB staff doubles (its notation staff). A doubling TAB part is engraved but never performed, has no
|
|
129
|
+
* annotation lanes and is not listed in part controls, so the instrument shows and plays once (lib/tab/tab-parts.ts).
|
|
130
|
+
*/
|
|
131
|
+
tabOf?: string;
|
|
125
132
|
};
|
|
126
133
|
export type Score = {
|
|
127
134
|
title: string;
|
|
@@ -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,58 @@
|
|
|
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
|
+
/** Notation parts that take TAB: every guitar part (and every part an imported TAB doubles), else the first pitched part. */
|
|
23
|
+
export declare function tabParts(score: Score): Part[];
|
|
24
|
+
/** Whether the Notation / TAB / Both switch has anything to switch. */
|
|
25
|
+
export declare const canShowTab: (score: Score) => boolean;
|
|
26
|
+
export type TabPlan = {
|
|
27
|
+
/** For the worker; absent when nothing is injected or retargeted. */
|
|
28
|
+
spec?: TabSpec;
|
|
29
|
+
/** Staff numbers hidden by the view (notation staves in TAB view, imported TAB staves when unused). */
|
|
30
|
+
hidden: string[];
|
|
31
|
+
/** Staff numbers the view adds or shows that are not in the baseline's staffDefs (generated TAB staves). */
|
|
32
|
+
added: string[];
|
|
33
|
+
/** The staff a notation part is read from in this view (its TAB staff in TAB view); defaults to its own. */
|
|
34
|
+
display: Map<string, string>;
|
|
35
|
+
/** Imported TAB part shown for a notation part (highlights map the notation part's notes onto it). */
|
|
36
|
+
importedFor: Map<string, Part>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The reader parts a saved record hides (`parts`: saved part states by ID). Only parts the reader lists can be hidden:
|
|
40
|
+
* a TAB part that doubles a guitar never is (an older reader listed it), and a guitar whose notation was hidden while
|
|
41
|
+
* its TAB part showed stays shown (the guitar was being read from its TAB).
|
|
42
|
+
*/
|
|
43
|
+
export declare function hiddenReaderParts(score: Score, parts: Record<string, PartState | undefined>): string[];
|
|
44
|
+
/**
|
|
45
|
+
* Plan a view: `staffOf` maps parts to baseline staff numbers, `hiddenIds` are parts the reader hid, `stale` is true
|
|
46
|
+
* when the view moves sounding pitches (transposition: imported `tab.fret`s no longer match, so imported TAB is replaced
|
|
47
|
+
* by generated TAB and a TAB-only staff is re-fingered). A concert view moves written notes to the pitches they already
|
|
48
|
+
* sound, so it never makes TAB stale. `sounding` lists staves whose spelled notes are at sounding pitch (their
|
|
49
|
+
* `trans.semi` no longer applies).
|
|
50
|
+
*/
|
|
51
|
+
export declare function planTab(score: Score, staffOf: Map<string, string>, view: TabView, options: {
|
|
52
|
+
tuning: number[];
|
|
53
|
+
capo: number;
|
|
54
|
+
stale: boolean;
|
|
55
|
+
semitones?: number;
|
|
56
|
+
sounding?: string[];
|
|
57
|
+
hiddenIds?: Set<string>;
|
|
58
|
+
}): TabPlan;
|