musicxml-io 0.2.5 → 0.2.8
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/README.md +162 -23
- package/dist/{index-CJUkJI2P.d.ts → index-B-GcfEfL.d.ts} +1 -1
- package/dist/{index-Hm73jOKD.d.mts → index-BvwdY5YQ.d.mts} +1 -1
- package/dist/index.d.mts +201 -7
- package/dist/index.d.ts +201 -7
- package/dist/index.js +184 -14
- package/dist/index.mjs +156 -14
- package/dist/operations/index.d.mts +2 -2
- package/dist/operations/index.d.ts +2 -2
- package/dist/operations/index.js +78 -15
- package/dist/operations/index.mjs +78 -15
- package/dist/query/index.d.mts +358 -2
- package/dist/query/index.d.ts +358 -2
- package/dist/query/index.js +1508 -2
- package/dist/query/index.mjs +1444 -1
- package/dist/{types-D3LhKCDK.d.mts → types-Bpq2o5JS.d.mts} +16 -1
- package/dist/{types-D3LhKCDK.d.ts → types-Bpq2o5JS.d.ts} +16 -1
- package/package.json +3 -2
- package/dist/accessors/index.d.mts +0 -360
- package/dist/accessors/index.d.ts +0 -360
- package/dist/accessors/index.js +0 -1537
- package/dist/accessors/index.mjs +0 -1448
package/README.md
CHANGED
|
@@ -13,25 +13,46 @@ TypeScript library for parsing and serializing MusicXML.
|
|
|
13
13
|
│ .xml / .mxl │─────▶│ Score │─────▶│ .xml / .mxl │
|
|
14
14
|
└─────────────────┘ │ │ └─────────────────┘
|
|
15
15
|
parse │ ┌─────────┐ │ serialize
|
|
16
|
-
│ │ parts
|
|
17
|
-
│ │ └─measures │
|
|
16
|
+
│ │ parts │ │ ┌─────────────────┐
|
|
17
|
+
│ │ └─measures │ │ MIDI │
|
|
18
18
|
│ │ └─entries│─────▶│ .mid │
|
|
19
19
|
│ └─────────┘ │ └─────────────────┘
|
|
20
20
|
│ │ exportMidi
|
|
21
21
|
└────────┬────────┘
|
|
22
22
|
│
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
┌───────────────────┼───────────────────┐
|
|
24
|
+
│ │ │
|
|
25
|
+
▼ ▼ ▼
|
|
26
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
27
|
+
│ QUERIES │ │ OPERATIONS │ │ ACCESSORS │
|
|
28
|
+
│ │ │ │ │ │
|
|
29
|
+
│ Score-level │ │ Score mutation │ │ Entry-level │
|
|
30
|
+
│ read operations │ │ operations │ │ helpers │
|
|
31
|
+
│ │ │ │ │ │
|
|
32
|
+
│ getMeasure() │ │ transpose() │ │ isRest() │
|
|
33
|
+
│ findNotes() │ │ addNote() │ │ isPitchedNote() │
|
|
34
|
+
│ getAllNotes() │ │ changeKey() │ │ getPartName() │
|
|
35
|
+
│ getHarmonies() │ │ insertMeasure() │ │ hasTie() │
|
|
36
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
37
|
+
│
|
|
38
|
+
▼
|
|
39
|
+
┌─────────────────┐
|
|
40
|
+
│ VALIDATE │
|
|
41
|
+
│ │
|
|
42
|
+
│ validate() │
|
|
43
|
+
│ isValid() │
|
|
44
|
+
│ assertValid() │
|
|
45
|
+
└─────────────────┘
|
|
33
46
|
```
|
|
34
47
|
|
|
48
|
+
### Module Structure
|
|
49
|
+
|
|
50
|
+
| Module | File | Description |
|
|
51
|
+
|--------|------|-------------|
|
|
52
|
+
| Query | `src/query/index.ts` | Score-level read operations (get, find, iterate) |
|
|
53
|
+
| Operations | `src/operations/index.ts` | Score mutation operations (add, delete, modify) |
|
|
54
|
+
| Accessors | `src/entry-accessors.ts` | Entry-level helpers for notes, directions, parts |
|
|
55
|
+
|
|
35
56
|
## Install
|
|
36
57
|
|
|
37
58
|
```bash
|
|
@@ -77,11 +98,49 @@ const waltz = changeTime(score, { beats: 3, beatType: 4 }, 0, 1);
|
|
|
77
98
|
### Query
|
|
78
99
|
|
|
79
100
|
```typescript
|
|
80
|
-
import { findNotes, getAllNotes, getMeasureCount } from 'musicxml-io';
|
|
101
|
+
import { findNotes, getAllNotes, getMeasureCount, getHarmonies } from 'musicxml-io';
|
|
81
102
|
|
|
82
103
|
const notes = getAllNotes(score);
|
|
83
|
-
const quarterNotes = findNotes(score, {
|
|
84
|
-
const count = getMeasureCount(score
|
|
104
|
+
const quarterNotes = findNotes(score, { noteType: 'quarter' });
|
|
105
|
+
const count = getMeasureCount(score);
|
|
106
|
+
const harmonies = getHarmonies(score); // chord symbols (C7, Dm, etc.)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Accessors
|
|
110
|
+
|
|
111
|
+
Entry-level helpers for working with individual notes, directions, and parts:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import {
|
|
115
|
+
getAllNotes,
|
|
116
|
+
isRest, isPitchedNote, hasTie, isChordNote,
|
|
117
|
+
getPartName,
|
|
118
|
+
getDirectionOfKind, getSoundTempo
|
|
119
|
+
} from 'musicxml-io';
|
|
120
|
+
|
|
121
|
+
// NoteEntry helpers
|
|
122
|
+
for (const item of getAllNotes(score)) {
|
|
123
|
+
if (isRest(item.note)) continue;
|
|
124
|
+
if (isPitchedNote(item.note)) {
|
|
125
|
+
console.log(`${item.note.pitch!.step}${item.note.pitch!.octave}`);
|
|
126
|
+
}
|
|
127
|
+
if (hasTie(item.note)) console.log('Tied note');
|
|
128
|
+
if (isChordNote(item.note)) console.log('Part of chord');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// PartInfo helpers
|
|
132
|
+
const partName = getPartName(score, 'P1'); // 'Piano'
|
|
133
|
+
|
|
134
|
+
// DirectionEntry helpers
|
|
135
|
+
for (const entry of measure.entries) {
|
|
136
|
+
if (entry.type === 'direction') {
|
|
137
|
+
const dynamics = getDirectionOfKind(entry, 'dynamics');
|
|
138
|
+
if (dynamics) console.log(dynamics.value); // 'ff', 'pp', etc.
|
|
139
|
+
|
|
140
|
+
const tempo = getSoundTempo(entry);
|
|
141
|
+
if (tempo) console.log(`Tempo: ${tempo} BPM`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
85
144
|
```
|
|
86
145
|
|
|
87
146
|
### MIDI Export
|
|
@@ -123,8 +182,10 @@ const { valid, errors } = validate(score);
|
|
|
123
182
|
| `addNote(score, options)` | Add note |
|
|
124
183
|
| `deleteNote(score, options)` | Delete note |
|
|
125
184
|
| `addChordNote(score, options)` | Add to chord |
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
185
|
+
| `modifyNotePitch(score, options)` | Change note pitch |
|
|
186
|
+
| `modifyNoteDuration(score, options)` | Change note duration |
|
|
187
|
+
| `changeKey(score, key, part, measure)` | Change key signature |
|
|
188
|
+
| `changeTime(score, time, part, measure)` | Change time signature |
|
|
128
189
|
| `insertMeasure(score, part, after)` | Insert measure |
|
|
129
190
|
| `deleteMeasure(score, part, measure)` | Delete measure |
|
|
130
191
|
|
|
@@ -132,12 +193,62 @@ const { valid, errors } = validate(score);
|
|
|
132
193
|
|
|
133
194
|
| Function | Description |
|
|
134
195
|
|----------|-------------|
|
|
135
|
-
| `getAllNotes(score)` | All notes |
|
|
136
|
-
| `findNotes(score, filter)` | Filter notes |
|
|
137
|
-
| `getMeasure(part,
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
196
|
+
| `getAllNotes(score)` | All notes with context |
|
|
197
|
+
| `findNotes(score, filter)` | Filter notes by criteria |
|
|
198
|
+
| `getMeasure(score, { part, measure })` | Get measure by number |
|
|
199
|
+
| `getMeasureByIndex(score, { part, measureIndex })` | Get measure by index |
|
|
200
|
+
| `getMeasureCount(score)` | Total measure count |
|
|
201
|
+
| `getChords(measure)` | Chord groups in measure |
|
|
202
|
+
| `countNotes(score)` | Total note count |
|
|
203
|
+
| `getHarmonies(score)` | All chord symbols |
|
|
204
|
+
| `getDynamics(score)` | All dynamics markings |
|
|
205
|
+
| `getTempoMarkings(score)` | All tempo markings |
|
|
206
|
+
|
|
207
|
+
### Accessors
|
|
208
|
+
|
|
209
|
+
Entry-level helpers for individual notes, directions, and parts.
|
|
210
|
+
|
|
211
|
+
**NoteEntry**
|
|
212
|
+
|
|
213
|
+
| Function | Description |
|
|
214
|
+
|----------|-------------|
|
|
215
|
+
| `isRest(note)` | Check if rest |
|
|
216
|
+
| `isPitchedNote(note)` | Check if has pitch |
|
|
217
|
+
| `isUnpitchedNote(note)` | Check if percussion |
|
|
218
|
+
| `isChordNote(note)` | Check if part of chord |
|
|
219
|
+
| `isGraceNote(note)` | Check if grace note |
|
|
220
|
+
| `isCueNote(note)` | Check if cue note |
|
|
221
|
+
| `hasTie(note)` | Check if tied |
|
|
222
|
+
| `hasTieStart(note)` | Check if tie starts |
|
|
223
|
+
| `hasTieStop(note)` | Check if tie stops |
|
|
224
|
+
| `hasBeam(note)` | Check if beamed |
|
|
225
|
+
| `hasLyrics(note)` | Check if has lyrics |
|
|
226
|
+
| `hasNotations(note)` | Check if has notations |
|
|
227
|
+
| `hasTuplet(note)` | Check if in tuplet |
|
|
228
|
+
|
|
229
|
+
**DirectionEntry**
|
|
230
|
+
|
|
231
|
+
| Function | Description |
|
|
232
|
+
|----------|-------------|
|
|
233
|
+
| `getDirectionOfKind(entry, kind)` | Get first direction type |
|
|
234
|
+
| `getDirectionsOfKind(entry, kind)` | Get all direction types |
|
|
235
|
+
| `hasDirectionOfKind(entry, kind)` | Check if has type |
|
|
236
|
+
| `getSoundTempo(entry)` | Get tempo from sound |
|
|
237
|
+
| `getSoundDynamics(entry)` | Get dynamics (0-127) |
|
|
238
|
+
| `getSoundDamperPedal(entry)` | Get damper pedal state |
|
|
239
|
+
| `getSoundSoftPedal(entry)` | Get soft pedal state |
|
|
240
|
+
| `getSoundSostenutoPedal(entry)` | Get sostenuto pedal state |
|
|
241
|
+
|
|
242
|
+
**PartInfo**
|
|
243
|
+
|
|
244
|
+
| Function | Description |
|
|
245
|
+
|----------|-------------|
|
|
246
|
+
| `getPartInfo(score, id)` | Get part info by ID |
|
|
247
|
+
| `getPartName(score, id)` | Get part name |
|
|
248
|
+
| `getPartAbbreviation(score, id)` | Get part abbreviation |
|
|
249
|
+
| `getAllPartInfos(score)` | Get all part infos |
|
|
250
|
+
| `getPartNameMap(score)` | Get ID to name map |
|
|
251
|
+
| `isPartInfo(entry)` | Type guard for PartInfo |
|
|
141
252
|
|
|
142
253
|
### Validate
|
|
143
254
|
|
|
@@ -152,8 +263,36 @@ const { valid, errors } = validate(score);
|
|
|
152
263
|
```typescript
|
|
153
264
|
import { transpose } from 'musicxml-io/operations';
|
|
154
265
|
import { findNotes } from 'musicxml-io/query';
|
|
266
|
+
import { isRest, getPartName } from 'musicxml-io/entry-accessors';
|
|
155
267
|
```
|
|
156
268
|
|
|
269
|
+
## Unique Element IDs
|
|
270
|
+
|
|
271
|
+
All elements in the Score structure have a unique `_id` property that is automatically generated when:
|
|
272
|
+
- MusicXML is parsed/imported
|
|
273
|
+
- New elements are created via operations
|
|
274
|
+
|
|
275
|
+
The ID format is `"i" + nanoid(10)` (11 characters total), where:
|
|
276
|
+
- `"i"` prefix ensures XML ID compatibility (IDs must start with a letter or underscore)
|
|
277
|
+
- `nanoid(10)` generates a URL-safe unique identifier
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import { parse, generateId } from 'musicxml-io';
|
|
281
|
+
|
|
282
|
+
const score = parse(xmlString);
|
|
283
|
+
console.log(score._id); // e.g., "iV1StGXR8_Z"
|
|
284
|
+
console.log(score.parts[0]._id); // e.g., "i2x4K9mL1Qp"
|
|
285
|
+
|
|
286
|
+
// Generate IDs manually for custom elements
|
|
287
|
+
const customId = generateId(); // e.g., "iAb3Cd5Ef7H"
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
This feature enables:
|
|
291
|
+
- Tracking elements across transformations
|
|
292
|
+
- Building element references in external systems
|
|
293
|
+
- Implementing undo/redo functionality
|
|
294
|
+
- Diffing and merging scores
|
|
295
|
+
|
|
157
296
|
## Round-trip Fidelity
|
|
158
297
|
|
|
159
298
|
| Metric | Score |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as Score, M as Measure, n as TimeSignature,
|
|
1
|
+
import { S as Score, M as Measure, n as TimeSignature, f as Part, N as NoteEntry, K as KeySignature, P as Pitch, C as Clef, ac as ArticulationType, m as DynamicsValue, ad as OrnamentType, i as NoteType } from './types-Bpq2o5JS.js';
|
|
2
2
|
|
|
3
3
|
type ValidationErrorCode = 'MISSING_DIVISIONS' | 'INVALID_DIVISIONS' | 'MEASURE_DURATION_MISMATCH' | 'MEASURE_DURATION_OVERFLOW' | 'MEASURE_DURATION_UNDERFLOW' | 'VOICE_INCOMPLETE' | 'VOICE_GAP' | 'NEGATIVE_POSITION' | 'BACKUP_EXCEEDS_POSITION' | 'TIE_START_WITHOUT_STOP' | 'TIE_STOP_WITHOUT_START' | 'TIE_PITCH_MISMATCH' | 'BEAM_BEGIN_WITHOUT_END' | 'BEAM_END_WITHOUT_BEGIN' | 'SLUR_START_WITHOUT_STOP' | 'SLUR_STOP_WITHOUT_START' | 'TUPLET_START_WITHOUT_STOP' | 'TUPLET_STOP_WITHOUT_START' | 'PART_ID_NOT_IN_PART_LIST' | 'PART_LIST_ID_NOT_IN_PARTS' | 'PART_MEASURE_COUNT_MISMATCH' | 'PART_MEASURE_NUMBER_MISMATCH' | 'PART_GROUP_START_WITHOUT_STOP' | 'PART_GROUP_STOP_WITHOUT_START' | 'DUPLICATE_PART_ID' | 'INVALID_VOICE_NUMBER' | 'INVALID_STAFF_NUMBER' | 'STAFF_EXCEEDS_STAVES' | 'MISSING_STAVES_DECLARATION' | 'STAVES_DECLARATION_MISMATCH' | 'MISSING_CLEF_FOR_STAFF' | 'CLEF_STAFF_EXCEEDS_STAVES' | 'INVALID_DURATION' | 'EMPTY_MEASURE';
|
|
4
4
|
type ValidationLevel = 'error' | 'warning' | 'info';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as Score, M as Measure, n as TimeSignature,
|
|
1
|
+
import { S as Score, M as Measure, n as TimeSignature, f as Part, N as NoteEntry, K as KeySignature, P as Pitch, C as Clef, ac as ArticulationType, m as DynamicsValue, ad as OrnamentType, i as NoteType } from './types-Bpq2o5JS.mjs';
|
|
2
2
|
|
|
3
3
|
type ValidationErrorCode = 'MISSING_DIVISIONS' | 'INVALID_DIVISIONS' | 'MEASURE_DURATION_MISMATCH' | 'MEASURE_DURATION_OVERFLOW' | 'MEASURE_DURATION_UNDERFLOW' | 'VOICE_INCOMPLETE' | 'VOICE_GAP' | 'NEGATIVE_POSITION' | 'BACKUP_EXCEEDS_POSITION' | 'TIE_START_WITHOUT_STOP' | 'TIE_STOP_WITHOUT_START' | 'TIE_PITCH_MISMATCH' | 'BEAM_BEGIN_WITHOUT_END' | 'BEAM_END_WITHOUT_BEGIN' | 'SLUR_START_WITHOUT_STOP' | 'SLUR_STOP_WITHOUT_START' | 'TUPLET_START_WITHOUT_STOP' | 'TUPLET_STOP_WITHOUT_START' | 'PART_ID_NOT_IN_PART_LIST' | 'PART_LIST_ID_NOT_IN_PARTS' | 'PART_MEASURE_COUNT_MISMATCH' | 'PART_MEASURE_NUMBER_MISMATCH' | 'PART_GROUP_START_WITHOUT_STOP' | 'PART_GROUP_STOP_WITHOUT_START' | 'DUPLICATE_PART_ID' | 'INVALID_VOICE_NUMBER' | 'INVALID_STAFF_NUMBER' | 'STAFF_EXCEEDS_STAVES' | 'MISSING_STAVES_DECLARATION' | 'STAVES_DECLARATION_MISMATCH' | 'MISSING_CLEF_FOR_STAFF' | 'CLEF_STAFF_EXCEEDS_STAVES' | 'INVALID_DURATION' | 'EMPTY_MEASURE';
|
|
4
4
|
type ValidationLevel = 'error' | 'warning' | 'info';
|
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { S as Score, P as Pitch, M as Measure } from './types-
|
|
2
|
-
export { A as Accidental,
|
|
3
|
-
import { V as ValidateOptions, a as ValidationResult } from './index-
|
|
4
|
-
export { L as LocalValidateOptions, M as MeasureValidationContext, G as ValidationError, I as ValidationErrorCode, C as ValidationException, J as ValidationLevel, H as ValidationLocation, g as addChordNote, b as addNote, F as assertMeasureValid, k as assertValid, c as changeKey, e as changeTime, f as deleteMeasure, d as deleteNote, B as formatLocation, E as getMeasureContext, i as insertMeasure, j as isValid, h as modifyNoteDuration, m as modifyNotePitch, t as transpose, v as validate, o as validateBackupForward, q as validateBeams, l as validateDivisions, n as validateMeasureDuration, D as validateMeasureLocal, u as validatePartReferences, w as validatePartStructure, r as validateSlurs, A as validateSlursAcrossMeasures, x as validateStaffStructure, p as validateTies, z as validateTiesAcrossMeasures, s as validateTuplets, y as validateVoiceStaff } from './index-
|
|
5
|
-
export { NormalizedPositionOptions, VoiceFilter, buildVoiceToStaffMap, buildVoiceToStaffMapForPart, findBarlines, findDirectionsByType, findNotesWithNotation, getAbsolutePosition, getAdjacentNotes, getAllNotes, getBeamGroups, getChordProgression, getChords, getClefChanges, getClefForStaff, getDirections, getDirectionsAtPosition, getDynamics, getEffectiveStaff, getEndings, getEntriesAtPosition, getEntriesForStaff, getEntriesInRange, getHarmonies, getHarmonyAtPosition, getKeyChanges, getLyricText, getLyrics, getNextNote, getNormalizedDuration, getNormalizedPosition, getNotesAtPosition, getNotesForStaff, getNotesForVoice, getNotesInRange, getOctaveShifts, getPartByIndex, getPartCount, getPartIds, getPedalMarkings, getPrevNote, getRepeatStructure, getSlurSpans, getStaffRange, getStaves, getStructuralChanges, getTempoMarkings, getTiedNoteGroups, getTimeChanges, getTupletGroups, getVerseCount, getVerticalSlice, getVoiceLine, getVoiceLineInRange, getVoices, getVoicesForStaff, getWedges, groupByStaff, groupByVoice, hasNotes, inferStaff, isRestMeasure, iterateEntries, iterateNotes, withAbsolutePositions } from './
|
|
6
|
-
export { FindNotesFilter, PitchRange, RoundtripMetrics, countNotes, findNotes, getAttributesAtMeasure, getDivisions, getDuration, getMeasure, getMeasureByIndex, getMeasureCount, getPartById, getPartIndex, getStaveCount, hasMultipleStaves, measureRoundtrip, scoresEqual } from './query/index.mjs';
|
|
1
|
+
import { S as Score, P as Pitch, M as Measure, D as DirectionType, a as DirectionEntry, N as NoteEntry, b as PartListEntry, c as PartInfo } from './types-Bpq2o5JS.mjs';
|
|
2
|
+
export { A as Accidental, j as AccidentalInfo, O as AdjacentNotes, a4 as AssembledLyrics, B as BackupEntry, p as Barline, a5 as BarlineWithContext, a0 as BeamGroup, k as BeamInfo, s as Chord, C as Clef, aa as ClefChangeInfo, w as Credit, v as Defaults, Q as DirectionKind, z as DirectionWithContext, R as DynamicWithContext, m as DynamicsValue, a7 as EndingInfo, E as EntryWithContext, F as ForwardEntry, a2 as HarmonyWithContext, a8 as KeyChangeInfo, K as KeySignature, L as Lyric, a3 as LyricWithContext, g as MeasureAttributes, h as MeasureEntry, l as Notation, a1 as NotationType, t as NoteIteratorItem, i as NoteType, y as NoteWithContext, r as NoteWithPosition, Y as OctaveShiftWithContext, f as Part, e as PartGroup, W as PedalWithContext, H as PositionQueryOptions, u as Print, a6 as RepeatInfo, d as ScoreMetadata, _ as SlurSpan, q as StaffGroup, G as StaffRange, ab as StructuralChanges, U as TempoWithContext, T as TieInfo, Z as TiedNoteGroup, a9 as TimeChangeInfo, n as TimeSignature, o as Transpose, $ as TupletGroup, I as VerticalSlice, V as VoiceGroup, J as VoiceLine, x as VoiceToStaffMap, X as WedgeWithContext } from './types-Bpq2o5JS.mjs';
|
|
3
|
+
import { V as ValidateOptions, a as ValidationResult } from './index-BvwdY5YQ.mjs';
|
|
4
|
+
export { L as LocalValidateOptions, M as MeasureValidationContext, G as ValidationError, I as ValidationErrorCode, C as ValidationException, J as ValidationLevel, H as ValidationLocation, g as addChordNote, b as addNote, F as assertMeasureValid, k as assertValid, c as changeKey, e as changeTime, f as deleteMeasure, d as deleteNote, B as formatLocation, E as getMeasureContext, i as insertMeasure, j as isValid, h as modifyNoteDuration, m as modifyNotePitch, t as transpose, v as validate, o as validateBackupForward, q as validateBeams, l as validateDivisions, n as validateMeasureDuration, D as validateMeasureLocal, u as validatePartReferences, w as validatePartStructure, r as validateSlurs, A as validateSlursAcrossMeasures, x as validateStaffStructure, p as validateTies, z as validateTiesAcrossMeasures, s as validateTuplets, y as validateVoiceStaff } from './index-BvwdY5YQ.mjs';
|
|
5
|
+
export { FindNotesFilter, NormalizedPositionOptions, PitchRange, RoundtripMetrics, VoiceFilter, buildVoiceToStaffMap, buildVoiceToStaffMapForPart, countNotes, findBarlines, findDirectionsByType, findNotes, findNotesWithNotation, getAbsolutePosition, getAdjacentNotes, getAllNotes, getAttributesAtMeasure, getBeamGroups, getChordProgression, getChords, getClefChanges, getClefForStaff, getDirections, getDirectionsAtPosition, getDivisions, getDuration, getDynamics, getEffectiveStaff, getEndings, getEntriesAtPosition, getEntriesForStaff, getEntriesInRange, getHarmonies, getHarmonyAtPosition, getKeyChanges, getLyricText, getLyrics, getMeasure, getMeasureByIndex, getMeasureCount, getNextNote, getNormalizedDuration, getNormalizedPosition, getNotesAtPosition, getNotesForStaff, getNotesForVoice, getNotesInRange, getOctaveShifts, getPartById, getPartByIndex, getPartCount, getPartIds, getPartIndex, getPedalMarkings, getPrevNote, getRepeatStructure, getSlurSpans, getStaffRange, getStaveCount, getStaves, getStructuralChanges, getTempoMarkings, getTiedNoteGroups, getTimeChanges, getTupletGroups, getVerseCount, getVerticalSlice, getVoiceLine, getVoiceLineInRange, getVoices, getVoicesForStaff, getWedges, groupByStaff, groupByVoice, hasMultipleStaves, hasNotes, inferStaff, isRestMeasure, iterateEntries, iterateNotes, measureRoundtrip, scoresEqual, withAbsolutePositions } from './query/index.mjs';
|
|
7
6
|
|
|
8
7
|
declare function parse(xmlString: string): Score;
|
|
9
8
|
|
|
@@ -104,4 +103,199 @@ declare function pitchToSemitone(pitch: Pitch): number;
|
|
|
104
103
|
/** Get position at end of measure */
|
|
105
104
|
declare function getMeasureEndPosition(measure: Measure): number;
|
|
106
105
|
|
|
107
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Entry-level accessors for DirectionEntry, NoteEntry, and PartInfo
|
|
108
|
+
*
|
|
109
|
+
* These are simple helper functions for working with individual entries,
|
|
110
|
+
* complementing the score-level query functions in ./query.
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Extracts a specific DirectionType union member by its kind
|
|
115
|
+
*/
|
|
116
|
+
type DirectionTypeOfKind<K extends DirectionType['kind']> = Extract<DirectionType, {
|
|
117
|
+
kind: K;
|
|
118
|
+
}>;
|
|
119
|
+
/**
|
|
120
|
+
* Get the first direction type of a specific kind from a DirectionEntry
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* const dynamics = getDirectionOfKind(entry, 'dynamics');
|
|
124
|
+
* if (dynamics) {
|
|
125
|
+
* console.log(dynamics.value); // 'ff', 'pp', etc.
|
|
126
|
+
* }
|
|
127
|
+
*/
|
|
128
|
+
declare function getDirectionOfKind<K extends DirectionType['kind']>(entry: DirectionEntry, kind: K): DirectionTypeOfKind<K> | undefined;
|
|
129
|
+
/**
|
|
130
|
+
* Get all direction types of a specific kind from a DirectionEntry
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* const allWords = getDirectionsOfKind(entry, 'words');
|
|
134
|
+
* allWords.forEach(w => console.log(w.text));
|
|
135
|
+
*/
|
|
136
|
+
declare function getDirectionsOfKind<K extends DirectionType['kind']>(entry: DirectionEntry, kind: K): DirectionTypeOfKind<K>[];
|
|
137
|
+
/**
|
|
138
|
+
* Check if a DirectionEntry contains a specific direction type
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* if (hasDirectionOfKind(entry, 'metronome')) {
|
|
142
|
+
* // Handle tempo marking
|
|
143
|
+
* }
|
|
144
|
+
*/
|
|
145
|
+
declare function hasDirectionOfKind(entry: DirectionEntry, kind: DirectionType['kind']): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Get tempo from DirectionEntry.sound
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* const tempo = getSoundTempo(entry); // 120
|
|
151
|
+
*/
|
|
152
|
+
declare function getSoundTempo(entry: DirectionEntry): number | undefined;
|
|
153
|
+
/**
|
|
154
|
+
* Get dynamics value from DirectionEntry.sound (MIDI velocity 0-127)
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* const dynamics = getSoundDynamics(entry); // 80
|
|
158
|
+
*/
|
|
159
|
+
declare function getSoundDynamics(entry: DirectionEntry): number | undefined;
|
|
160
|
+
/**
|
|
161
|
+
* Get damper pedal state from DirectionEntry.sound
|
|
162
|
+
*/
|
|
163
|
+
declare function getSoundDamperPedal(entry: DirectionEntry): 'yes' | 'no' | undefined;
|
|
164
|
+
/**
|
|
165
|
+
* Get soft pedal state from DirectionEntry.sound
|
|
166
|
+
*/
|
|
167
|
+
declare function getSoundSoftPedal(entry: DirectionEntry): 'yes' | 'no' | undefined;
|
|
168
|
+
/**
|
|
169
|
+
* Get sostenuto pedal state from DirectionEntry.sound
|
|
170
|
+
*/
|
|
171
|
+
declare function getSoundSostenutoPedal(entry: DirectionEntry): 'yes' | 'no' | undefined;
|
|
172
|
+
/**
|
|
173
|
+
* Check if a NoteEntry is a rest
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* if (isRest(note)) {
|
|
177
|
+
* console.log('This is a rest');
|
|
178
|
+
* }
|
|
179
|
+
*/
|
|
180
|
+
declare function isRest(entry: NoteEntry): boolean;
|
|
181
|
+
/**
|
|
182
|
+
* Check if a NoteEntry is a pitched note (has pitch information)
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* if (isPitchedNote(note)) {
|
|
186
|
+
* console.log(`Note: ${note.pitch!.step}${note.pitch!.octave}`);
|
|
187
|
+
* }
|
|
188
|
+
*/
|
|
189
|
+
declare function isPitchedNote(entry: NoteEntry): boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Check if a NoteEntry is an unpitched note (percussion)
|
|
192
|
+
*/
|
|
193
|
+
declare function isUnpitchedNote(entry: NoteEntry): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Check if a NoteEntry is part of a chord (shares onset with previous note)
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* const chordNotes = notes.filter(isChordNote);
|
|
199
|
+
*/
|
|
200
|
+
declare function isChordNote(entry: NoteEntry): boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Check if a NoteEntry is a grace note
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* if (isGraceNote(note)) {
|
|
206
|
+
* console.log('Grace note with slash:', note.grace?.slash);
|
|
207
|
+
* }
|
|
208
|
+
*/
|
|
209
|
+
declare function isGraceNote(entry: NoteEntry): boolean;
|
|
210
|
+
/**
|
|
211
|
+
* Check if a NoteEntry has any tie (start, stop, or continue)
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* if (hasTie(note)) {
|
|
215
|
+
* // Note is tied to another note
|
|
216
|
+
* }
|
|
217
|
+
*/
|
|
218
|
+
declare function hasTie(entry: NoteEntry): boolean;
|
|
219
|
+
/**
|
|
220
|
+
* Check if a NoteEntry has a tie start
|
|
221
|
+
*/
|
|
222
|
+
declare function hasTieStart(entry: NoteEntry): boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Check if a NoteEntry has a tie stop
|
|
225
|
+
*/
|
|
226
|
+
declare function hasTieStop(entry: NoteEntry): boolean;
|
|
227
|
+
/**
|
|
228
|
+
* Check if a NoteEntry is a cue note
|
|
229
|
+
*/
|
|
230
|
+
declare function isCueNote(entry: NoteEntry): boolean;
|
|
231
|
+
/**
|
|
232
|
+
* Check if a NoteEntry has any beams
|
|
233
|
+
*/
|
|
234
|
+
declare function hasBeam(entry: NoteEntry): boolean;
|
|
235
|
+
/**
|
|
236
|
+
* Check if a NoteEntry has any lyrics
|
|
237
|
+
*/
|
|
238
|
+
declare function hasLyrics(entry: NoteEntry): boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Check if a NoteEntry has any notations (articulations, slurs, ornaments, etc.)
|
|
241
|
+
*/
|
|
242
|
+
declare function hasNotations(entry: NoteEntry): boolean;
|
|
243
|
+
/**
|
|
244
|
+
* Check if a NoteEntry is part of a tuplet
|
|
245
|
+
*/
|
|
246
|
+
declare function hasTuplet(entry: NoteEntry): boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Check if a PartListEntry is a PartInfo (score-part)
|
|
249
|
+
*/
|
|
250
|
+
declare function isPartInfo(entry: PartListEntry): entry is PartInfo;
|
|
251
|
+
/**
|
|
252
|
+
* Get PartInfo by part ID
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* const partInfo = getPartInfo(score, 'P1');
|
|
256
|
+
* if (partInfo) {
|
|
257
|
+
* console.log(partInfo.name); // 'Piano'
|
|
258
|
+
* }
|
|
259
|
+
*/
|
|
260
|
+
declare function getPartInfo(score: Score, partId: string): PartInfo | undefined;
|
|
261
|
+
/**
|
|
262
|
+
* Get part name by part ID
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* const name = getPartName(score, 'P1'); // 'Piano'
|
|
266
|
+
*/
|
|
267
|
+
declare function getPartName(score: Score, partId: string): string | undefined;
|
|
268
|
+
/**
|
|
269
|
+
* Get part abbreviation by part ID
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* const abbr = getPartAbbreviation(score, 'P1'); // 'Pno.'
|
|
273
|
+
*/
|
|
274
|
+
declare function getPartAbbreviation(score: Score, partId: string): string | undefined;
|
|
275
|
+
/**
|
|
276
|
+
* Get all PartInfo entries from a score
|
|
277
|
+
*/
|
|
278
|
+
declare function getAllPartInfos(score: Score): PartInfo[];
|
|
279
|
+
/**
|
|
280
|
+
* Get a map of part ID to part name
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* const names = getPartNameMap(score);
|
|
284
|
+
* // { 'P1': 'Piano', 'P2': 'Violin' }
|
|
285
|
+
*/
|
|
286
|
+
declare function getPartNameMap(score: Score): Record<string, string | undefined>;
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Generates a unique ID for elements in the Score structure.
|
|
290
|
+
*
|
|
291
|
+
* The ID format is "i" + nanoid(10), where:
|
|
292
|
+
* - "i" prefix ensures XML ID compatibility (XML IDs must start with a letter or underscore)
|
|
293
|
+
* - nanoid(10) generates a 10-character URL-safe unique identifier
|
|
294
|
+
*
|
|
295
|
+
* Example: "iV1StGXR8_"
|
|
296
|
+
*
|
|
297
|
+
* @returns A unique 11-character ID string
|
|
298
|
+
*/
|
|
299
|
+
declare function generateId(): string;
|
|
300
|
+
|
|
301
|
+
export { DirectionEntry, DirectionType, type DirectionTypeOfKind, Measure, type MidiExportOptions, NoteEntry, PartInfo, PartListEntry, Pitch, STEPS, STEP_SEMITONES, Score, type SerializeOptions, ValidateOptions, ValidationResult, decodeBuffer, exportMidi, generateId, getAllPartInfos, getDirectionOfKind, getDirectionsOfKind, getMeasureEndPosition, getPartAbbreviation, getPartInfo, getPartName, getPartNameMap, getSoundDamperPedal, getSoundDynamics, getSoundSoftPedal, getSoundSostenutoPedal, getSoundTempo, hasBeam, hasDirectionOfKind, hasLyrics, hasNotations, hasTie, hasTieStart, hasTieStop, hasTuplet, isChordNote, isCompressed, isCueNote, isGraceNote, isPartInfo, isPitchedNote, isRest, isUnpitchedNote, parse, parseAuto, parseCompressed, parseFile, pitchToSemitone, serialize, serializeCompressed, serializeToFile };
|