@stringsync/vexml
Version:
MusicXML to Vexflow
331 lines (330 loc) • 10.8 kB
JavaScript
import * as util from '../util';
/** A wrapper around {@link data.Document} that provides querying capabilities. */
export class Document {
data;
constructor(data) {
this.data = data;
}
getTitle() {
return this.data.score.title;
}
getPartLabel(key) {
return this.data.score.partLabels.at(key.partIndex) ?? '';
}
getScore() {
return this.data.score;
}
getCurves() {
return this.data.score.curves;
}
getCurve(key) {
const curve = this.getCurves().at(key.curveIndex);
util.assertDefined(curve);
return curve;
}
getWedges() {
return this.data.score.wedges;
}
getWedge(key) {
const wedge = this.getWedges().at(key.wedgeIndex);
util.assertDefined(wedge);
return wedge;
}
getPedals() {
return this.data.score.pedals;
}
getPedal(key) {
const pedal = this.getPedals().at(key.pedalIndex);
util.assertDefined(pedal);
return pedal;
}
getOctaveShifts() {
return this.data.score.octaveShifts;
}
getOctaveShift(key) {
const octaveShift = this.getOctaveShifts().at(key.octaveShiftIndex);
util.assertDefined(octaveShift);
return octaveShift;
}
getOctaveShiftKey(id) {
const octaveShift = this.data.score.octaveShifts.find((o) => o.id === id);
util.assertDefined(octaveShift);
return { octaveShiftIndex: this.data.score.octaveShifts.indexOf(octaveShift) };
}
getVibratos() {
return this.data.score.vibratos;
}
getVibrato(key) {
const vibrato = this.getVibratos().at(key.vibratoIndex);
util.assertDefined(vibrato);
return vibrato;
}
getSystems() {
return this.data.score.systems;
}
getSystemCount() {
return this.getSystems().length;
}
isFirstSystem(key) {
return key.systemIndex === 0;
}
isLastSystem(key) {
return key.systemIndex === this.getSystemCount() - 1;
}
getPreviousSystem(key) {
if (key.systemIndex > 0) {
const previousSystem = this.getSystems().at(key.systemIndex - 1);
util.assertDefined(previousSystem);
return previousSystem;
}
return null;
}
getSystem(key) {
const system = this.getSystems().at(key.systemIndex);
util.assertDefined(system);
return system;
}
getNextSystem(key) {
if (key.systemIndex < this.getSystemCount() - 1) {
const nextSystem = this.getSystems().at(key.systemIndex + 1);
util.assertDefined(nextSystem);
return nextSystem;
}
return null;
}
getMeasures(key) {
return this.getSystem(key).measures;
}
getMeasureCount(key) {
return this.getMeasures(key).length;
}
isFirstMeasure(key) {
return key.measureIndex === 0;
}
isLastMeasure(key) {
return key.measureIndex === this.getMeasureCount(key) - 1;
}
getPreviousMeasure(key) {
if (key.measureIndex > 0) {
const previousMeasure = this.getMeasures(key).at(key.measureIndex - 1);
util.assertDefined(previousMeasure);
return previousMeasure;
}
return this.getPreviousSystem(key)?.measures.at(-1) ?? null;
}
getMeasure(key) {
const measure = this.getMeasures(key).at(key.measureIndex);
util.assertDefined(measure);
return measure;
}
getNextMeasure(key) {
if (key.measureIndex < this.getMeasureCount(key) - 1) {
const nextMeasure = this.getMeasures(key).at(key.measureIndex + 1);
util.assertDefined(nextMeasure);
return nextMeasure;
}
return this.getNextSystem(key)?.measures.at(0) ?? null;
}
getMeasureMultiRestCount(key) {
let measureMultiRestCount = -1;
const fragmentCount = this.getFragmentCount(key);
for (let fragmentIndex = 0; fragmentIndex < fragmentCount; fragmentIndex++) {
const fragmentKey = { ...key, fragmentIndex };
const partCount = this.getPartCount(fragmentKey);
for (let partIndex = 0; partIndex < partCount; partIndex++) {
const partKey = { ...fragmentKey, partIndex };
const staveCount = this.getStaveCount(partKey);
for (let staveIndex = 0; staveIndex < staveCount; staveIndex++) {
const staveKey = { ...partKey, staveIndex };
if (measureMultiRestCount === -1) {
measureMultiRestCount = this.getStaveMultiRestCount(staveKey);
}
else {
measureMultiRestCount = Math.min(measureMultiRestCount, this.getStaveMultiRestCount(staveKey));
}
}
}
}
return Math.max(0, measureMultiRestCount);
}
getAbsoluteMeasureIndex(key) {
const measures = this.getSystems().flatMap((s) => s.measures);
return measures.indexOf(this.getMeasure(key));
}
getFragments(key) {
return this.getMeasure(key).fragments;
}
getFragmentCount(key) {
return this.getFragments(key).length;
}
isFirstFragment(key) {
return key.fragmentIndex === 0;
}
isLastFragment(key) {
return key.fragmentIndex === this.getFragmentCount(key) - 1;
}
getPreviousFragment(key) {
if (key.fragmentIndex > 0) {
const previousEntry = this.getFragments(key).at(key.fragmentIndex - 1);
util.assertDefined(previousEntry);
return previousEntry;
}
return this.getPreviousMeasure(key)?.fragments.at(-1) ?? null;
}
getFragment(key) {
const entry = this.getFragments(key).at(key.fragmentIndex);
util.assertDefined(entry);
return entry;
}
getNonMusicalFragment(key) {
const fragment = this.getFragment(key);
util.assert(fragment.kind === 'nonmusical', 'expected a non-musical fragment');
return fragment;
}
getNextFragment(key) {
if (key.fragmentIndex < this.getFragmentCount(key) - 1) {
const nextEntry = this.getFragments(key).at(key.fragmentIndex + 1);
util.assertDefined(nextEntry);
return nextEntry;
}
return this.getNextMeasure(key)?.fragments.at(0) ?? null;
}
getParts(key) {
return this.getFragment(key).parts;
}
getPartCount(key) {
return this.getParts(key).length;
}
isFirstPart(key) {
return key.partIndex === 0;
}
isLastPart(key) {
return key.partIndex === this.getPartCount(key) - 1;
}
getPartMultiRestCount(key) {
return Math.min(...this.getStaves(key).map((s) => s.multiRestCount));
}
getPart(key) {
const part = this.getParts(key).at(key.partIndex);
util.assertDefined(part);
return part;
}
getStaves(key) {
return this.getPart(key).staves;
}
getStaveCount(key) {
return this.getPart(key).signature.staveCount;
}
isFirstStave(key) {
return key.staveIndex === 0;
}
isLastStave(key) {
return key.staveIndex === this.getStaveCount(key) - 1;
}
isTabStave(key) {
return this.getStave(key).signature.clef.sign === 'tab';
}
getStaveMultiRestCount(key) {
return this.getStave(key).multiRestCount;
}
getPreviouslyPlayedStave(key) {
return this.getPreviousFragment(key)?.parts.at(key.partIndex)?.staves.at(key.staveIndex) ?? null;
}
getStave(key) {
const stave = this.getStaves(key).at(key.staveIndex);
util.assertDefined(stave);
return stave;
}
getNextPlayedStave(key) {
return this.getNextFragment(key)?.parts.at(key.partIndex)?.staves.at(key.staveIndex) ?? null;
}
getVoices(key) {
return this.getStave(key).voices;
}
getVoiceCount(key) {
return this.getVoices(key).length;
}
isFirstVoice(key) {
return key.voiceIndex === 0;
}
isLastVoice(key) {
return key.voiceIndex === this.getVoiceCount(key) - 1;
}
getVoice(key) {
const voice = this.getVoices(key).at(key.voiceIndex);
util.assertDefined(voice);
return voice;
}
getBeams(key) {
return this.getVoice(key).beams;
}
getBeamCount(key) {
return this.getBeams(key).length;
}
getBeam(key) {
const beam = this.getBeams(key).at(key.beamIndex);
util.assertDefined(beam);
return beam;
}
getTuplets(key) {
return this.getVoice(key).tuplets;
}
getTupletCount(key) {
return this.getTuplets(key).length;
}
getTuplet(key) {
const tuplet = this.getTuplets(key).at(key.tupletIndex);
util.assertDefined(tuplet);
return tuplet;
}
getVoiceEntries(key) {
return this.getVoice(key).entries;
}
getVoiceEntryCount(key) {
return this.getVoiceEntries(key).length;
}
isFirstVoiceEntry(key) {
return key.voiceEntryIndex === 0;
}
isLastVoiceEntry(key) {
return key.voiceEntryIndex === this.getVoiceEntryCount(key) - 1;
}
getVoiceEntry(key) {
const entry = this.getVoiceEntries(key).at(key.voiceEntryIndex);
util.assertDefined(entry);
return entry;
}
getNote(key) {
const entry = this.getVoiceEntries(key).at(key.voiceEntryIndex);
util.assert(entry?.type === 'note', 'expected entry to be a note');
return entry;
}
getRest(key) {
const entry = this.getVoiceEntries(key).at(key.voiceEntryIndex);
util.assert(entry?.type === 'rest', 'expected entry to be a rest');
return entry;
}
getChord(key) {
const entry = this.getVoiceEntries(key).at(key.voiceEntryIndex);
util.assert(entry?.type === 'chord', 'expected entry to be a chord');
return entry;
}
getDynamics(key) {
const entry = this.getVoiceEntries(key).at(key.voiceEntryIndex);
util.assert(entry?.type === 'dynamics', 'expected entry to be dynamics');
return entry;
}
getArticulations(key) {
const entry = this.getVoiceEntries(key).at(key.voiceEntryIndex);
util.assert(entry?.type === 'note' || entry?.type === 'chord', 'expected entry to be a note or chord');
return entry.articulations;
}
getArticulation(key) {
const articulation = this.getArticulations(key).at(key.articulationIndex);
util.assertDefined(articulation);
return articulation;
}
clone() {
return new Document(this.data.clone());
}
}