@scorelabs/viewer 1.0.1

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.
Files changed (83) hide show
  1. package/README.md +5 -0
  2. package/dist/android-chrome-192x192.png +0 -0
  3. package/dist/android-chrome-512x512.png +0 -0
  4. package/dist/apple-touch-icon.png +0 -0
  5. package/dist/audio/AudioPlayer.d.ts +54 -0
  6. package/dist/favicon-16x16.png +0 -0
  7. package/dist/favicon-32x32.png +0 -0
  8. package/dist/favicon-96x96.png +0 -0
  9. package/dist/favicon.ico +0 -0
  10. package/dist/favicon.svg +1 -0
  11. package/dist/importers/MusicXMLParser.d.ts +51 -0
  12. package/dist/importers/index.d.ts +6 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/layouts/LayoutConfig.d.ts +62 -0
  15. package/dist/layouts/LayoutUtils.d.ts +10 -0
  16. package/dist/layouts/MeasureLayout.d.ts +20 -0
  17. package/dist/layouts/NoteLayout.d.ts +21 -0
  18. package/dist/layouts/ScoreLayout.d.ts +28 -0
  19. package/dist/layouts/StaffLayout.d.ts +26 -0
  20. package/dist/layouts/StaffSystemLayout.d.ts +18 -0
  21. package/dist/layouts/index.d.ts +6 -0
  22. package/dist/models/Instrument.d.ts +26 -0
  23. package/dist/models/Measure.d.ts +80 -0
  24. package/dist/models/Note.d.ts +122 -0
  25. package/dist/models/Part.d.ts +60 -0
  26. package/dist/models/Pitch.d.ts +45 -0
  27. package/dist/models/Score.d.ts +120 -0
  28. package/dist/models/Staff.d.ts +57 -0
  29. package/dist/models/__tests__/Note.test.d.ts +1 -0
  30. package/dist/models/__tests__/Pitch.test.d.ts +1 -0
  31. package/dist/models/index.d.ts +7 -0
  32. package/dist/models/types.d.ts +163 -0
  33. package/dist/new_score.json +112 -0
  34. package/dist/rendering/NoteRenderer.d.ts +52 -0
  35. package/dist/rendering/ScoreRenderer.d.ts +35 -0
  36. package/dist/rendering/StaffRenderer.d.ts +67 -0
  37. package/dist/rendering/glyphs/AccidentalGlyphs.d.ts +5 -0
  38. package/dist/rendering/glyphs/ClefGlyphs.d.ts +19 -0
  39. package/dist/rendering/glyphs/DecorationGlyphs.d.ts +11 -0
  40. package/dist/rendering/glyphs/NoteGlyphs.d.ts +19 -0
  41. package/dist/rendering/glyphs/RestGlyphs.d.ts +11 -0
  42. package/dist/rendering/glyphs/SignatureGlyphs.d.ts +11 -0
  43. package/dist/rendering/glyphs/index.d.ts +6 -0
  44. package/dist/rendering/index.d.ts +4 -0
  45. package/dist/satb.xml +4 -0
  46. package/dist/score-viewer.js +13234 -0
  47. package/dist/score-viewer.umd.cjs +145 -0
  48. package/dist/scores/canon_pachelbel.xml +4 -0
  49. package/dist/scores/el_cant_dels_ocells.xml +112 -0
  50. package/dist/scores/el_noi_de_la_mare.xml +102 -0
  51. package/dist/scores/els_segadors.xml +110 -0
  52. package/dist/scores/imported/forest.xml +161 -0
  53. package/dist/showcase.json +292 -0
  54. package/dist/site.webmanifest +21 -0
  55. package/dist/src/App.d.ts +1 -0
  56. package/dist/src/components/AboutDialog.d.ts +6 -0
  57. package/dist/src/components/ChordDialog.d.ts +8 -0
  58. package/dist/src/components/ClefDialog.d.ts +9 -0
  59. package/dist/src/components/FloatingToolbar.d.ts +26 -0
  60. package/dist/src/components/InstrumentsDialog.d.ts +22 -0
  61. package/dist/src/components/KeySignatureDialog.d.ts +9 -0
  62. package/dist/src/components/Logo.d.ts +6 -0
  63. package/dist/src/components/MenuBar.d.ts +20 -0
  64. package/dist/src/components/NoteInputToolbar.d.ts +101 -0
  65. package/dist/src/components/PageSetupDialog.d.ts +9 -0
  66. package/dist/src/components/ScoreCanvas.d.ts +49 -0
  67. package/dist/src/components/ScoreInfoDialog.d.ts +19 -0
  68. package/dist/src/components/ScoreLayoutDialog.d.ts +9 -0
  69. package/dist/src/components/TempoDialog.d.ts +11 -0
  70. package/dist/src/components/TextDialog.d.ts +10 -0
  71. package/dist/src/components/TimeSignatureDialog.d.ts +9 -0
  72. package/dist/src/components/TransposeDialog.d.ts +9 -0
  73. package/dist/src/components/VirtualKeyboard.d.ts +10 -0
  74. package/dist/src/exporters/MusicXMLExporter.d.ts +10 -0
  75. package/dist/src/hooks/useHistory.d.ts +14 -0
  76. package/dist/src/index.d.ts +24 -0
  77. package/dist/src/main.d.ts +1 -0
  78. package/dist/src/services/HarmonyService.d.ts +10 -0
  79. package/dist/src/services/VocalSynthesisService.d.ts +13 -0
  80. package/dist/src/utils/pdfToPng.d.ts +5 -0
  81. package/dist/web-app-manifest-192x192.png +0 -0
  82. package/dist/web-app-manifest-512x512.png +0 -0
  83. package/package.json +63 -0
@@ -0,0 +1,51 @@
1
+ import { ScoreJSON } from '../models/Score';
2
+ /**
3
+ * MusicXML Parser class
4
+ */
5
+ export declare class MusicXMLParser {
6
+ private currentKeyFifths;
7
+ private currentBeats;
8
+ private currentBeatType;
9
+ /**
10
+ * Parse a MusicXML string and return ScoreJSON
11
+ */
12
+ parse(xmlString: string): ScoreJSON;
13
+ /**
14
+ * Parse work title or movement title
15
+ */
16
+ private parseTitle;
17
+ /**
18
+ * Parse composer from identification/creator
19
+ */
20
+ private parseComposer;
21
+ /**
22
+ * Parse part-list to get part names
23
+ */
24
+ private parsePartList;
25
+ /**
26
+ * Parse a single part into multiple staves if present
27
+ */
28
+ /**
29
+ * Parse all parts
30
+ */
31
+ private parseParts;
32
+ /**
33
+ * Parse a single part into multiple staves if present
34
+ */
35
+ private parsePart;
36
+ /**
37
+ * Parse a single note element
38
+ */
39
+ private parseNote;
40
+ private stepToNumber;
41
+ /**
42
+ * Professional Musical Post-Processing
43
+ */
44
+ postProcess(score: ScoreJSON): ScoreJSON;
45
+ private cleanAccidentals;
46
+ private applyBeaming;
47
+ }
48
+ /**
49
+ * Utility function to load and parse a MusicXML file
50
+ */
51
+ export declare function loadMusicXML(url: string): Promise<ScoreJSON>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Importers module
3
+ *
4
+ * Provides utilities for importing various music file formats into Score format.
5
+ */
6
+ export { MusicXMLParser, loadMusicXML } from './MusicXMLParser';
@@ -0,0 +1,2 @@
1
+ export * from './src/index'
2
+ export {}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Layout engine configuration
3
+ */
4
+ export interface LayoutConfig {
5
+ canvasWidth: number;
6
+ marginTop: number;
7
+ marginLeft: number;
8
+ marginRight: number;
9
+ marginBottom: number;
10
+ titleHeight: number;
11
+ staffLineSpacing: number;
12
+ staffMargin: number;
13
+ systemMargin: number;
14
+ measuresPerLine: number;
15
+ clefWidth: number;
16
+ trebleClefYOffset: number;
17
+ bassClefYOffset: number;
18
+ noteDotDistance: number;
19
+ titleSubtitleSpacing: number;
20
+ subtitleScoreSpacing: number;
21
+ minNoteSpacing: number;
22
+ firstSystemIndentation: number;
23
+ musicFont: 'Standard' | 'Jazz';
24
+ showMeasureNumbers: boolean;
25
+ measureNumberMode: 'system' | 'interval' | 'measure';
26
+ measureNumberInterval: number;
27
+ showPartNames: boolean;
28
+ groupMultiMeasureRests: boolean;
29
+ titleStyle: TextStyle;
30
+ subtitleStyle: TextStyle;
31
+ composerStyle: TextStyle;
32
+ pageWidth: number;
33
+ pageHeight: number;
34
+ tempoStyle: TextStyle;
35
+ clefKeySignatureSpacing: number;
36
+ noteNameMode: 'none' | 'alphabetical' | 'solfege';
37
+ bassClefScale: number;
38
+ trebleClefScale: number;
39
+ clefLeftPadding: number;
40
+ midMeasureClefWidth: number;
41
+ keySignatureStepWidth: number;
42
+ keySignatureRightPadding: number;
43
+ timeSignatureWidth: number;
44
+ }
45
+ /**
46
+ * Text style configuration
47
+ */
48
+ export interface TextStyle {
49
+ fontFamily: string;
50
+ fontSize: number;
51
+ fontWeight: 'normal' | 'bold';
52
+ fontStyle: 'normal' | 'italic';
53
+ }
54
+ /**
55
+ * Default layout configuration
56
+ */
57
+ export declare const DEFAULT_LAYOUT_CONFIG: LayoutConfig;
58
+ /**
59
+ * Resolves a LayoutConfig by multiplying all relative values by staffLineSpacing.
60
+ * This ensures that proportions remain constant as staffLineSpacing (zoom) changes.
61
+ */
62
+ export declare function resolveLayoutConfig(config: LayoutConfig): LayoutConfig;
@@ -0,0 +1,10 @@
1
+ import { Clef } from '../models/types';
2
+ import { LayoutConfig } from './LayoutConfig';
3
+ /**
4
+ * Calculates the width of a clef symbol based on configuration.
5
+ */
6
+ export declare function getClefWidth(clef: Clef, config: LayoutConfig): number;
7
+ /**
8
+ * Calculates the width of a key signature based on number of accidentals.
9
+ */
10
+ export declare function getKeySignatureWidth(fifths: number, config: LayoutConfig): number;
@@ -0,0 +1,20 @@
1
+ import { Measure } from '../models';
2
+ import { Clef, TimeSignature } from '../models/types';
3
+ import { NoteLayout } from './NoteLayout';
4
+ import { LayoutConfig } from './LayoutConfig';
5
+ /**
6
+ * Layout information for a measure.
7
+ */
8
+ export interface MeasureLayout {
9
+ measure: Measure;
10
+ x: number;
11
+ width: number;
12
+ voiceLayouts: NoteLayout[][];
13
+ noteLayouts: NoteLayout[];
14
+ measureNumber: number;
15
+ signatureWidth?: number;
16
+ }
17
+ /**
18
+ * Calculate measure layout
19
+ */
20
+ export declare function calculateMeasureLayout(measure: Measure, measureNumber: number, x: number, width: number, staffY: number, clef: Clef, currentTimeSignature: TimeSignature, config: LayoutConfig, lineCount?: number): MeasureLayout;
@@ -0,0 +1,21 @@
1
+ import { Note } from '../models';
2
+ import { Clef, StemDirection } from '../models/types';
3
+ /**
4
+ * Layout information for a single note.
5
+ */
6
+ export interface NoteLayout {
7
+ note: Note;
8
+ x: number;
9
+ y: number;
10
+ staffPosition: number;
11
+ stemDirection: StemDirection;
12
+ stemStartY: number;
13
+ stemEndY: number;
14
+ clef: Clef;
15
+ voiceIndex: number;
16
+ noteIndex: number;
17
+ }
18
+ /**
19
+ * Calculate note layout
20
+ */
21
+ export declare function calculateNoteLayout(note: Note, x: number, staffY: number, staffLineSpacing: number, clef: Clef, lineCount?: number, voiceIndex?: number, noteIndex?: number): NoteLayout;
@@ -0,0 +1,28 @@
1
+ import { Score } from '../models';
2
+ import { StaffSystemLayout } from './StaffSystemLayout';
3
+ import { LayoutConfig } from './LayoutConfig';
4
+ /**
5
+ * Layout for a single page.
6
+ */
7
+ export interface PageLayout {
8
+ width: number;
9
+ height: number;
10
+ systemLayouts: StaffSystemLayout[];
11
+ titleY?: number;
12
+ subtitleY?: number;
13
+ composerY?: number;
14
+ lyricistY?: number;
15
+ copyrightY?: number;
16
+ }
17
+ /**
18
+ * Top-level layout for the entire score.
19
+ */
20
+ export interface ScoreLayout {
21
+ pages: PageLayout[];
22
+ totalWidth: number;
23
+ totalHeight: number;
24
+ }
25
+ /**
26
+ * Calculate complete score layout distributed across pages
27
+ */
28
+ export declare function calculateScoreLayout(score: Score, configRaw?: LayoutConfig, visiblePartIndices?: number[]): ScoreLayout;
@@ -0,0 +1,26 @@
1
+ import { Staff } from '../models';
2
+ import { Clef, KeySignature, TimeSignature } from '../models/types';
3
+ import { MeasureLayout } from './MeasureLayout';
4
+ import { LayoutConfig } from './LayoutConfig';
5
+ /**
6
+ * Layout information for a staff.
7
+ */
8
+ export interface StaffLayout {
9
+ staff: Staff;
10
+ x: number;
11
+ y: number;
12
+ width: number;
13
+ height: number;
14
+ clef: Clef;
15
+ measureLayouts: MeasureLayout[];
16
+ partIndex: number;
17
+ staffIndex: number;
18
+ keySignature: KeySignature;
19
+ timeSignature: TimeSignature;
20
+ maxClefWidth: number;
21
+ maxKeySignatureWidth: number;
22
+ }
23
+ /**
24
+ * Calculate staff layout
25
+ */
26
+ export declare function calculateStaffLayout(staff: Staff, partIndex: number, staffIndex: number, x: number, y: number, width: number, measureStartIndex: number, measuresPerLine: number, keySignature: KeySignature, timeSignature: TimeSignature, config: LayoutConfig, measureNumberStartIndex?: number, maxClefWidth?: number, maxKeySignatureWidth?: number, measureWidths?: number[]): StaffLayout;
@@ -0,0 +1,18 @@
1
+ import { Score } from '../models';
2
+ import { StaffLayout } from './StaffLayout';
3
+ import { KeySignature, TimeSignature } from '../models/types';
4
+ import { LayoutConfig } from './LayoutConfig';
5
+ /**
6
+ * Layout for a staff system (one horizontal row of staves).
7
+ */
8
+ export interface StaffSystemLayout {
9
+ y: number;
10
+ height: number;
11
+ staffLayouts: StaffLayout[];
12
+ measureStartIndex: number;
13
+ measuresInSystem: number;
14
+ }
15
+ /**
16
+ * Calculate staff system layout
17
+ */
18
+ export declare function calculateStaffSystemLayout(score: Score, x: number, y: number, width: number, measureStartIndex: number, measuresPerLine: number, keySignature: KeySignature, timeSignature: TimeSignature, config: LayoutConfig, measureNumberStartIndex?: number): StaffSystemLayout;
@@ -0,0 +1,6 @@
1
+ export * from './NoteLayout';
2
+ export * from './MeasureLayout';
3
+ export * from './StaffLayout';
4
+ export * from './StaffSystemLayout';
5
+ export * from './ScoreLayout';
6
+ export * from './LayoutConfig';
@@ -0,0 +1,26 @@
1
+ export declare enum InstrumentType {
2
+ String = "string",
3
+ Brass = "brass",
4
+ Woodwind = "woodwind",
5
+ Percussion = "percussion",
6
+ Keyboard = "keyboard",
7
+ Synth = "synth"
8
+ }
9
+ export declare enum InstrumentPreset {
10
+ Piano = "piano",
11
+ Violin = "violin",
12
+ Cello = "cello",
13
+ Guitar = "guitar",
14
+ ElectricGuitar = "electric-guitar",
15
+ Bass = "bass",
16
+ Flute = "flute",
17
+ Trumpet = "trumpet",
18
+ Drums = "drums"
19
+ }
20
+ export interface Instrument {
21
+ name: string;
22
+ midiProgram: number;
23
+ type?: InstrumentType;
24
+ }
25
+ export declare const PRESET_INSTRUMENTS: Record<string, Instrument>;
26
+ export declare function getInstrumentByProgram(program: number): Instrument;
@@ -0,0 +1,80 @@
1
+ import { Note, NoteJSON } from './Note';
2
+ import { TimeSignature, KeySignature, Duration, Repeat, Volta, Clef, Tempo } from './types';
3
+ /**
4
+ * Represents a single measure containing notes, potentially in multiple voices.
5
+ */
6
+ export declare class Measure {
7
+ readonly voices: Note[][];
8
+ readonly timeSignature?: TimeSignature | undefined;
9
+ readonly keySignature?: KeySignature | undefined;
10
+ readonly systemBreak: boolean;
11
+ readonly pageBreak: boolean;
12
+ readonly repeats: Repeat[];
13
+ readonly volta?: Volta | undefined;
14
+ readonly isPickup: boolean;
15
+ readonly clef?: Clef | undefined;
16
+ readonly tempo?: Tempo | undefined;
17
+ readonly rehearsalMark?: string | undefined;
18
+ readonly systemText?: string | undefined;
19
+ constructor(voices: Note[][], timeSignature?: TimeSignature | undefined, // Only if changes mid-piece
20
+ keySignature?: KeySignature | undefined, // Only if changes mid-piece
21
+ systemBreak?: boolean, pageBreak?: boolean, repeats?: Repeat[], volta?: Volta | undefined, isPickup?: boolean, clef?: Clef | undefined, tempo?: Tempo | undefined, rehearsalMark?: string | undefined, systemText?: string | undefined);
22
+ /**
23
+ * Backward compatibility property for single-voice logic.
24
+ * Returns the first voice.
25
+ */
26
+ get notes(): Note[];
27
+ /**
28
+ * Change the duration of a note in a specific voice
29
+ */
30
+ changeNoteDuration(noteIndex: number, newDuration: Duration, isDotted?: boolean, voiceIndex?: number): Measure;
31
+ getTotalDuration(voiceIndex?: number): number;
32
+ /**
33
+ * Create a Measure from JSON data
34
+ */
35
+ static fromJSON(data: MeasureJSON): Measure;
36
+ transpose(semitones: number): Measure;
37
+ replaceNote(noteIndex: number, newNote: Note, voiceIndex?: number): Measure;
38
+ deleteNote(noteIndex: number, voiceIndex?: number): Measure;
39
+ /**
40
+ * Automatically update beaming based on time signature
41
+ */
42
+ autoBeam(timeSign: TimeSignature): Measure;
43
+ withTimeSignature(timeSignature?: TimeSignature): Measure;
44
+ withKeySignature(keySignature?: KeySignature): Measure;
45
+ withClef(clef?: Clef): Measure;
46
+ withTempo(tempo?: Tempo): Measure;
47
+ withSystemBreak(systemBreak: boolean): Measure;
48
+ withPageBreak(pageBreak: boolean): Measure;
49
+ withVoices(voices: Note[][]): Measure;
50
+ withRepeat(repeat?: Repeat): Measure;
51
+ withRepeats(repeats: Repeat[]): Measure;
52
+ withVolta(volta?: Volta): Measure;
53
+ withPickup(isPickup: boolean): Measure;
54
+ withRehearsalMark(mark?: string): Measure;
55
+ withSystemText(text?: string): Measure;
56
+ /**
57
+ * Fills a specific voice with rests to match the measure's duration.
58
+ */
59
+ fillVoiceWithRests(voiceIndex: number, targetDuration: number): Measure;
60
+ toJSON(): MeasureJSON;
61
+ }
62
+ /**
63
+ * JSON interface for serialization
64
+ */
65
+ export interface MeasureJSON {
66
+ notes?: NoteJSON[];
67
+ voices?: NoteJSON[][];
68
+ timeSignature?: TimeSignature;
69
+ keySignature?: KeySignature;
70
+ systemBreak?: boolean;
71
+ pageBreak?: boolean;
72
+ repeat?: Repeat;
73
+ repeats?: Repeat[];
74
+ volta?: Volta;
75
+ isPickup?: boolean;
76
+ clef?: Clef;
77
+ tempo?: Tempo;
78
+ rehearsalMark?: string;
79
+ systemText?: string;
80
+ }
@@ -0,0 +1,122 @@
1
+ import { Duration, Accidental, Articulation, Dynamic, Slur, Tuplet, Hairpin, Glissando, Arpeggio, Ottava, Pedal, Ornament, FretboardDiagram, NoteheadShape, Bowing } from './types';
2
+ import { Pitch } from './Pitch';
3
+ /**
4
+ * Represents a single note or rest in a measure.
5
+ */
6
+ export declare class Note {
7
+ readonly duration: Duration;
8
+ readonly pitch?: Pitch | undefined;
9
+ readonly isRest: boolean;
10
+ readonly isDotted: boolean;
11
+ readonly accidental?: Accidental | undefined;
12
+ readonly beamGroup?: number | undefined;
13
+ readonly articulation?: Articulation | undefined;
14
+ readonly dynamic?: Dynamic | undefined;
15
+ readonly tie?: boolean | undefined;
16
+ readonly slur?: Slur | undefined;
17
+ readonly tuplet?: Tuplet | undefined;
18
+ readonly hairpin?: Hairpin | undefined;
19
+ readonly isGrace: boolean;
20
+ readonly lyric?: string | undefined;
21
+ readonly chord?: string | undefined;
22
+ readonly glissando?: Glissando | undefined;
23
+ readonly arpeggio?: Arpeggio | undefined;
24
+ readonly ottava?: Ottava | undefined;
25
+ readonly pedal?: Pedal | undefined;
26
+ readonly ornament?: Ornament | undefined;
27
+ readonly fret?: number | undefined;
28
+ readonly string?: number | undefined;
29
+ readonly fretboardDiagram?: FretboardDiagram | undefined;
30
+ readonly lyrics?: string[] | undefined;
31
+ readonly staffText?: string | undefined;
32
+ readonly color?: string | undefined;
33
+ readonly notehead?: NoteheadShape | undefined;
34
+ readonly bowing?: Bowing | undefined;
35
+ readonly fingering?: number | undefined;
36
+ constructor(duration: Duration, pitch?: Pitch | undefined, // undefined for rests
37
+ isRest?: boolean, isDotted?: boolean, accidental?: Accidental | undefined, beamGroup?: number | undefined, // Group ID for beamed notes
38
+ articulation?: Articulation | undefined, dynamic?: Dynamic | undefined, tie?: boolean | undefined, slur?: Slur | undefined, tuplet?: Tuplet | undefined, hairpin?: Hairpin | undefined, isGrace?: boolean, lyric?: string | undefined, chord?: string | undefined, glissando?: Glissando | undefined, arpeggio?: Arpeggio | undefined, ottava?: Ottava | undefined, pedal?: Pedal | undefined, ornament?: Ornament | undefined, fret?: number | undefined, string?: number | undefined, fretboardDiagram?: FretboardDiagram | undefined, lyrics?: string[] | undefined, staffText?: string | undefined, color?: string | undefined, notehead?: NoteheadShape | undefined, bowing?: Bowing | undefined, fingering?: number | undefined);
39
+ /**
40
+ * Get the duration value (quarter note = 1)
41
+ */
42
+ getDurationValue(): number;
43
+ /**
44
+ * Check if this note should be beamed (eighth or shorter)
45
+ */
46
+ isBeamable(): boolean;
47
+ withGrace(isGrace: boolean): Note;
48
+ withChord(chord?: string): Note;
49
+ /**
50
+ * Create a note from JSON data
51
+ */
52
+ static fromJSON(data: NoteJSON): Note;
53
+ transpose(semitones: number): Note;
54
+ transposeOctave(octaves: number): Note;
55
+ transposeDiatonic(steps: number): Note;
56
+ toggleEnharmonic(): Note;
57
+ withPitch(pitch: Pitch): Note;
58
+ withArticulation(articulation?: Articulation): Note;
59
+ withDynamic(dynamic?: Dynamic): Note;
60
+ withTie(tie?: boolean): Note;
61
+ withSlur(slur?: Slur): Note;
62
+ withTuplet(tuplet?: Tuplet): Note;
63
+ withLyric(lyric?: string): Note;
64
+ withLyrics(lyrics: string[]): Note;
65
+ withHairpin(hairpin?: Hairpin): Note;
66
+ withAccidental(accidental?: Accidental): Note;
67
+ withDuration(duration: Duration, isDotted?: boolean): Note;
68
+ withRest(isRest: boolean): Note;
69
+ withFretboardDiagram(diagram?: FretboardDiagram): Note;
70
+ withBeamGroup(beamGroup?: number): Note;
71
+ toJSON(): NoteJSON;
72
+ withGlissando(glissando?: Glissando): Note;
73
+ withArpeggio(arpeggio?: Arpeggio): Note;
74
+ withOttava(ottava?: Ottava): Note;
75
+ withPedal(pedal?: Pedal): Note;
76
+ withOrnament(ornament?: Ornament): Note;
77
+ withTab(fret: number, string: number): Note;
78
+ withStaffText(text?: string): Note;
79
+ withColor(color?: string): Note;
80
+ withNotehead(notehead?: NoteheadShape): Note;
81
+ withBowing(bowing?: Bowing): Note;
82
+ withFingering(fingering?: number): Note;
83
+ }
84
+ /**
85
+ * JSON interface for serialization
86
+ */
87
+ export interface NoteJSON {
88
+ duration: string;
89
+ pitch?: {
90
+ midiNumber: number;
91
+ step?: number;
92
+ alter?: number;
93
+ octave?: number;
94
+ };
95
+ isRest?: boolean;
96
+ isDotted?: boolean;
97
+ accidental?: string;
98
+ beamGroup?: number;
99
+ articulation?: string;
100
+ dynamic?: string;
101
+ tie?: boolean;
102
+ slur?: Slur;
103
+ tuplet?: Tuplet;
104
+ hairpin?: Hairpin;
105
+ isGrace?: boolean;
106
+ lyric?: string;
107
+ chord?: string;
108
+ glissando?: Glissando;
109
+ arpeggio?: Arpeggio;
110
+ ottava?: Ottava;
111
+ pedal?: Pedal;
112
+ ornament?: Ornament;
113
+ fret?: number;
114
+ string?: number;
115
+ fretboardDiagram?: FretboardDiagram;
116
+ lyrics?: string[];
117
+ staffText?: string;
118
+ color?: string;
119
+ notehead?: string;
120
+ bowing?: string;
121
+ fingering?: number;
122
+ }
@@ -0,0 +1,60 @@
1
+ import { Staff, StaffJSON } from './Staff';
2
+ import { Instrument } from './Instrument';
3
+ import { Note } from './Note';
4
+ import { Measure } from './Measure';
5
+ import { Duration } from './types';
6
+ /**
7
+ * Represents a musical part (instrument/voice) which can have multiple staves.
8
+ * For example, a piano part typically has 2 staves (treble and bass).
9
+ */
10
+ export declare class Part {
11
+ readonly name: string;
12
+ readonly staves: Staff[];
13
+ readonly abbreviation: string;
14
+ readonly instrument: Instrument;
15
+ constructor(name: string, staves: Staff[], abbreviation?: string, instrument?: Instrument);
16
+ /**
17
+ * Check if this is a multi-staff part (like piano)
18
+ */
19
+ isMultiStaff(): boolean;
20
+ /**
21
+ * Get the total number of measures (from the first staff)
22
+ */
23
+ getMeasureCount(): number;
24
+ /**
25
+ * Create a Part from JSON data
26
+ */
27
+ static fromJSON(data: PartJSON): Part;
28
+ /**
29
+ * Transpose all staves in this part by semitones
30
+ */
31
+ transpose(semitones: number): Part;
32
+ /**
33
+ * Replace a note in a specific staff/measure
34
+ */
35
+ replaceNote(staffIndex: number, measureIndex: number, noteIndex: number, newNote: Note, voiceIndex?: number): Part;
36
+ replaceMeasure(staffIndex: number, measureIndex: number, newMeasure: Measure): Part;
37
+ /**
38
+ * Delete a note in a specific staff/measure
39
+ */
40
+ deleteNote(staffIndex: number, measureIndex: number, noteIndex: number, voiceIndex?: number): Part;
41
+ /**
42
+ * Change note duration in a specific staff/measure
43
+ */
44
+ changeNoteDuration(staffIndex: number, measureIndex: number, noteIndex: number, newDuration: Duration, isDotted?: boolean, voiceIndex?: number): Part;
45
+ /**
46
+ * Convert to JSON
47
+ */
48
+ toJSON(): PartJSON;
49
+ withInstrument(instrument: Instrument): Part;
50
+ replaceStaff(staffIndex: number, newStaff: Staff): Part;
51
+ withStaves(staves: Staff[]): Part;
52
+ addMeasure(index: number, measure: Measure): Part;
53
+ deleteMeasure(index: number): Part;
54
+ }
55
+ export interface PartJSON {
56
+ name: string;
57
+ staves: StaffJSON[];
58
+ abbreviation?: string;
59
+ instrument?: Instrument;
60
+ }
@@ -0,0 +1,45 @@
1
+ import { Clef } from './types';
2
+ /**
3
+ * Pitch representation using MIDI numbers and explicit spelling (step, alter, octave).
4
+ */
5
+ export declare class Pitch {
6
+ readonly midiNumber: number;
7
+ readonly step: number;
8
+ readonly alter: number;
9
+ readonly octave: number;
10
+ constructor(midiNumber: number, step?: number, alter?: number, octave?: number);
11
+ /**
12
+ * Get the note name (e.g., "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B")
13
+ * Note: This returns the default name for the midi number, not necessarily the spelled name.
14
+ */
15
+ getNoteName(): string;
16
+ /**
17
+ * Get the octave number (C4 = octave 4)
18
+ */
19
+ getOctave(): number;
20
+ /**
21
+ * Get staff position relative to the middle line of the staff.
22
+ */
23
+ getStaffPosition(clef: Clef): number;
24
+ /**
25
+ * Get absolute diatonic step count (octave * 7 + diatonic step)
26
+ */
27
+ getAbsoluteDiatonicStep(): number;
28
+ /**
29
+ * Get the diatonic step index (0-based from C).
30
+ */
31
+ getDiatonicStep(): number;
32
+ /**
33
+ * Move this pitch by a number of diatonic steps (staff lines/spaces).
34
+ */
35
+ transposeDiatonic(steps: number): Pitch;
36
+ /**
37
+ * Cycle to the next common enharmonic spelling.
38
+ */
39
+ withEnharmonicNext(): Pitch;
40
+ /**
41
+ * Create a Pitch from note name and octave
42
+ */
43
+ static fromNoteName(note: string, octave: number): Pitch;
44
+ static fromStaffPosition(clef: Clef, staffPosition: number): Pitch;
45
+ }