Andrea Condoluci 8 роки тому
батько
коміт
73d319fb17

+ 1 - 1
src/MusicalScore/Graphical/GraphicalLyricEntry.ts

@@ -7,7 +7,7 @@ import {TextAlignment} from "../../Common/Enums/TextAlignment";
 import {PointF2D} from "../../Common/DataObjects/PointF2D";
 import {PointF2D} from "../../Common/DataObjects/PointF2D";
 
 
 /**
 /**
- * The graphical counterpart of a [[LyricEntry]]
+ * The graphical counterpart of a [[LyricsEntry]]
  */
  */
 export class GraphicalLyricEntry {
 export class GraphicalLyricEntry {
     private lyricsEntry: LyricsEntry;
     private lyricsEntry: LyricsEntry;

+ 1 - 0
src/MusicalScore/Graphical/MusicSheetDrawer.ts

@@ -27,6 +27,7 @@ import {GraphicalObject} from "./GraphicalObject";
 
 
 /**
 /**
  * Draw a [[GraphicalMusicSheet]] (through the .drawSheet method)
  * Draw a [[GraphicalMusicSheet]] (through the .drawSheet method)
+ *
  * The drawing is implemented with a top-down approach, starting from a music sheet, going through pages, systems, staffs...
  * The drawing is implemented with a top-down approach, starting from a music sheet, going through pages, systems, staffs...
  * ... and ending in notes, beams, accidentals and other symbols.
  * ... and ending in notes, beams, accidentals and other symbols.
  * It's worth to say, that this class just draws the symbols and graphical elements, using the positions that have been computed before.
  * It's worth to say, that this class just draws the symbols and graphical elements, using the positions that have been computed before.

+ 65 - 1
src/MusicalScore/ScoreIO/InstrumentReader.ts

@@ -53,6 +53,7 @@ export type repetitionInstructionReader = any;
  * with the readNextXmlMeasure method.
  * with the readNextXmlMeasure method.
  */
  */
 export class InstrumentReader {
 export class InstrumentReader {
+
     constructor(repetitionInstructionReader: repetitionInstructionReader, xmlMeasureList: IXmlElement[], instrument: Instrument) {
     constructor(repetitionInstructionReader: repetitionInstructionReader, xmlMeasureList: IXmlElement[], instrument: Instrument) {
         // (*) this.repetitionInstructionReader = repetitionInstructionReader;
         // (*) this.repetitionInstructionReader = repetitionInstructionReader;
         this.xmlMeasureList = xmlMeasureList;
         this.xmlMeasureList = xmlMeasureList;
@@ -109,6 +110,13 @@ export class InstrumentReader {
         this.activeRhythm = value;
         this.activeRhythm = value;
     }
     }
 
 
+    /**
+     * Main CreateSheet: read the next XML Measure and save all data to the given [[SourceMeasure]].
+     * @param currentMeasure
+     * @param measureStartAbsoluteTimestamp - Using this instead of currentMeasure.AbsoluteTimestamp as it isn't set yet
+     * @param guitarPro
+     * @returns {boolean}
+     */
     public readNextXmlMeasure(currentMeasure: SourceMeasure, measureStartAbsoluteTimestamp: Fraction, guitarPro: boolean): boolean {
     public readNextXmlMeasure(currentMeasure: SourceMeasure, measureStartAbsoluteTimestamp: Fraction, guitarPro: boolean): boolean {
         if (this.currentXmlMeasureIndex >= this.xmlMeasureList.length) {
         if (this.currentXmlMeasureIndex >= this.xmlMeasureList.length) {
             return false;
             return false;
@@ -391,6 +399,12 @@ export class InstrumentReader {
         }
         }
     }
     }
 
 
+    /**
+     * Get or create the passing [[VoiceGenerator]].
+     * @param voiceId
+     * @param staffId
+     * @returns {VoiceGenerator}
+     */
     private getOrCreateVoiceGenerator(voiceId: number, staffId: number): VoiceGenerator {
     private getOrCreateVoiceGenerator(voiceId: number, staffId: number): VoiceGenerator {
         let staff: Staff = this.instrument.Staves[staffId];
         let staff: Staff = this.instrument.Staves[staffId];
         let voiceGenerator: VoiceGenerator = this.voiceGeneratorsDict[voiceId];
         let voiceGenerator: VoiceGenerator = this.voiceGeneratorsDict[voiceId];
@@ -423,7 +437,10 @@ export class InstrumentReader {
     //  //}
     //  //}
     //}
     //}
 
 
-
+    /**
+     * Create the default [[ClefInstruction]] for the given staff index.
+     * @param staffIndex
+     */
     private createDefaultClefInstruction(staffIndex: number): void {
     private createDefaultClefInstruction(staffIndex: number): void {
         let first: SourceMeasure;
         let first: SourceMeasure;
         if (this.musicSheet.SourceMeasures.length > 0) {
         if (this.musicSheet.SourceMeasures.length > 0) {
@@ -444,6 +461,9 @@ export class InstrumentReader {
         firstStaffEntry.Instructions.splice(0, 0, clefInstruction);
         firstStaffEntry.Instructions.splice(0, 0, clefInstruction);
     }
     }
 
 
+    /**
+     * Create the default [[KeyInstruction]] in case no [[KeyInstruction]] is given in the whole [[Instrument]].
+     */
     private createDefaultKeyInstruction(): void {
     private createDefaultKeyInstruction(): void {
         let first: SourceMeasure;
         let first: SourceMeasure;
         if (this.musicSheet.SourceMeasures.length > 0) {
         if (this.musicSheet.SourceMeasures.length > 0) {
@@ -471,6 +491,12 @@ export class InstrumentReader {
         }
         }
     }
     }
 
 
+    /**
+     * Check if the given attributesNode is at the begin of a XmlMeasure.
+     * @param parentNode
+     * @param attributesNode
+     * @returns {boolean}
+     */
     private isAttributesNodeAtBeginOfMeasure(parentNode: IXmlElement, attributesNode: IXmlElement): boolean {
     private isAttributesNodeAtBeginOfMeasure(parentNode: IXmlElement, attributesNode: IXmlElement): boolean {
         let children: IXmlElement[] = parentNode.elements();
         let children: IXmlElement[] = parentNode.elements();
         let attributesNodeIndex: number = children.indexOf(attributesNode); // FIXME | 0
         let attributesNodeIndex: number = children.indexOf(attributesNode); // FIXME | 0
@@ -487,6 +513,12 @@ export class InstrumentReader {
         return (attributesNodeIndex < firstNoteNodeIndex && firstNoteNodeIndex > 0) || (firstNoteNodeIndex < 0);
         return (attributesNodeIndex < firstNoteNodeIndex && firstNoteNodeIndex > 0) || (firstNoteNodeIndex < 0);
     }
     }
 
 
+    /**
+     * Check if the given attributesNode is at the end of a XmlMeasure.
+     * @param parentNode
+     * @param attributesNode
+     * @returns {boolean}
+     */
     private isAttributesNodeAtEndOfMeasure(parentNode: IXmlElement, attributesNode: IXmlElement): boolean {
     private isAttributesNodeAtEndOfMeasure(parentNode: IXmlElement, attributesNode: IXmlElement): boolean {
         let childs: IXmlElement[] = parentNode.elements().slice();
         let childs: IXmlElement[] = parentNode.elements().slice();
         let attributesNodeIndex: number = 0;
         let attributesNodeIndex: number = 0;
@@ -506,6 +538,11 @@ export class InstrumentReader {
         return attributesNodeIndex > nextNoteNodeIndex;
         return attributesNodeIndex > nextNoteNodeIndex;
     }
     }
 
 
+    /**
+     * Called only when no noteDuration is given in XML.
+     * @param xmlNode
+     * @returns {Fraction}
+     */
     private getNoteDurationFromTypeNode(xmlNode: IXmlElement): Fraction {
     private getNoteDurationFromTypeNode(xmlNode: IXmlElement): Fraction {
         if (xmlNode.element("type") !== undefined) {
         if (xmlNode.element("type") !== undefined) {
             let typeNode: IXmlElement = xmlNode.element("type");
             let typeNode: IXmlElement = xmlNode.element("type");
@@ -517,6 +554,11 @@ export class InstrumentReader {
         return new Fraction(0, 4 * this.divisions);
         return new Fraction(0, 4 * this.divisions);
     }
     }
 
 
+    /**
+     * Add (the three basic) Notation Instructions to a list
+     * @param node
+     * @param guitarPro
+     */
     private addAbstractInstruction(node: IXmlElement, guitarPro: boolean): void {
     private addAbstractInstruction(node: IXmlElement, guitarPro: boolean): void {
         if (node.element("divisions") !== undefined) {
         if (node.element("divisions") !== undefined) {
             if (node.elements().length === 1) {
             if (node.elements().length === 1) {
@@ -730,6 +772,11 @@ export class InstrumentReader {
         }
         }
     }
     }
 
 
+    /**
+     * Save the current AbstractInstructions to the corresponding [[StaffEntry]]s.
+     * @param numberOfStaves
+     * @param beginOfMeasure
+     */
     private saveAbstractInstructionList(numberOfStaves: number, beginOfMeasure: boolean): void {
     private saveAbstractInstructionList(numberOfStaves: number, beginOfMeasure: boolean): void {
         for (let i: number = this.abstractInstructions.length - 1; i >= 0; i--) {
         for (let i: number = this.abstractInstructions.length - 1; i >= 0; i--) {
             let pair: [number, AbstractNotationInstruction] = this.abstractInstructions[i];
             let pair: [number, AbstractNotationInstruction] = this.abstractInstructions[i];
@@ -869,6 +916,9 @@ export class InstrumentReader {
         }
         }
     }
     }
 
 
+    /**
+     * Save any ClefInstruction given - exceptionally - at the end of the currentMeasure.
+     */
     private saveClefInstructionAtEndOfMeasure(): void {
     private saveClefInstructionAtEndOfMeasure(): void {
         for (let i: number = this.abstractInstructions.length - 1; i >= 0; i--) {
         for (let i: number = this.abstractInstructions.length - 1; i >= 0; i--) {
             let key: number = this.abstractInstructions[i][0];
             let key: number = this.abstractInstructions[i][0];
@@ -893,6 +943,11 @@ export class InstrumentReader {
         }
         }
     }
     }
 
 
+    /**
+     * In case of a [[Tuplet]], read NoteDuration from type.
+     * @param xmlNode
+     * @returns {Fraction}
+     */
     private getNoteDurationForTuplet(xmlNode: IXmlElement): Fraction {
     private getNoteDurationForTuplet(xmlNode: IXmlElement): Fraction {
         let duration: Fraction = new Fraction(0, 1);
         let duration: Fraction = new Fraction(0, 1);
         let typeDuration: Fraction = this.getNoteDurationFromTypeNode(xmlNode);
         let typeDuration: Fraction = this.getNoteDurationFromTypeNode(xmlNode);
@@ -933,6 +988,15 @@ export class InstrumentReader {
     //  }
     //  }
     //  return directionStaffNumber;
     //  return directionStaffNumber;
     //}
     //}
+
+    /**
+     * Calculate the divisions value from the type and duration of the first MeasureNote that makes sense
+     * (meaning itself hasn't any errors and it doesn't belong to a [[Tuplet]]).
+     *
+     * If all the MeasureNotes belong to a [[Tuplet]], then we read the next XmlMeasure (and so on...).
+     * If we have reached the end of the [[Instrument]] and still the divisions aren't set, we throw an exception
+     * @returns {number}
+     */
     private readDivisionsFromNotes(): number {
     private readDivisionsFromNotes(): number {
         let divisionsFromNote: number = 0;
         let divisionsFromNote: number = 0;
         let xmlMeasureIndex: number = this.currentXmlMeasureIndex;
         let xmlMeasureIndex: number = this.currentXmlMeasureIndex;

+ 70 - 2
src/MusicalScore/ScoreIO/MusicSheetReader.ts

@@ -58,6 +58,12 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         }
         }
     }
     }
 
 
+    /**
+     * Read a music XML file and saves the values in the MusicSheet class.
+     * @param root
+     * @param path
+     * @returns {MusicSheet}
+     */
     public createMusicSheet(root: IXmlElement, path: string): MusicSheet {
     public createMusicSheet(root: IXmlElement, path: string): MusicSheet {
         try {
         try {
             return this._createMusicSheet(root, path);
             return this._createMusicSheet(root, path);
@@ -157,7 +163,7 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
             if (couldReadMeasure) {
             if (couldReadMeasure) {
                 this.musicSheet.addMeasure(this.currentMeasure);
                 this.musicSheet.addMeasure(this.currentMeasure);
                 this.checkIfRhythmInstructionsAreSetAndEqual(instrumentReaders);
                 this.checkIfRhythmInstructionsAreSetAndEqual(instrumentReaders);
-                this.checkSourceMeasureForundefinedEntries();
+                this.checkSourceMeasureForNullEntries();
                 sourceMeasureCounter = this.setSourceMeasureDuration(instrumentReaders, sourceMeasureCounter);
                 sourceMeasureCounter = this.setSourceMeasureDuration(instrumentReaders, sourceMeasureCounter);
                 MusicSheetReader.doCalculationsAfterDurationHasBeenSet(instrumentReaders);
                 MusicSheetReader.doCalculationsAfterDurationHasBeenSet(instrumentReaders);
                 this.currentMeasure.AbsoluteTimestamp = this.currentFraction.clone();
                 this.currentMeasure.AbsoluteTimestamp = this.currentFraction.clone();
@@ -221,6 +227,13 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         }
         }
     }
     }
 
 
+    /**
+     * Check if all (should there be any apart from the first Measure) [[RhythmInstruction]]s in the [[SourceMeasure]] are the same.
+     *
+     * If not, then the max [[RhythmInstruction]] (Fraction) is set to all staves.
+     * Also, if it happens to have the same [[RhythmInstruction]]s in RealValue but given in Symbol AND Fraction, then the Fraction prevails.
+     * @param instrumentReaders
+     */
     private checkIfRhythmInstructionsAreSetAndEqual(instrumentReaders: InstrumentReader[]): void {
     private checkIfRhythmInstructionsAreSetAndEqual(instrumentReaders: InstrumentReader[]): void {
         let rhythmInstructions: RhythmInstruction[] = [];
         let rhythmInstructions: RhythmInstruction[] = [];
         for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
         for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
@@ -302,6 +315,11 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         }
         }
     }
     }
 
 
+    /**
+     * True in case of 4/4 and COMMON TIME (or 2/2 and CUT TIME)
+     * @param rhythmInstructions
+     * @returns {boolean}
+     */
     private areRhythmInstructionsMixed(rhythmInstructions: RhythmInstruction[]): boolean {
     private areRhythmInstructionsMixed(rhythmInstructions: RhythmInstruction[]): boolean {
         for (let i: number = 1; i < rhythmInstructions.length; i++) {
         for (let i: number = 1; i < rhythmInstructions.length; i++) {
             if (
             if (
@@ -314,6 +332,12 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         return false;
         return false;
     }
     }
 
 
+    /**
+     * Set the [[Measure]]'s duration taking into account the longest [[Instrument]] duration and the active Rhythm read from XML.
+     * @param instrumentReaders
+     * @param sourceMeasureCounter
+     * @returns {number}
+     */
     private setSourceMeasureDuration(instrumentReaders: InstrumentReader[], sourceMeasureCounter: number): number {
     private setSourceMeasureDuration(instrumentReaders: InstrumentReader[], sourceMeasureCounter: number): number {
         let activeRhythm: Fraction = new Fraction(0, 1);
         let activeRhythm: Fraction = new Fraction(0, 1);
         let instrumentsMaxTieNoteFractions: Fraction[] = [];
         let instrumentsMaxTieNoteFractions: Fraction[] = [];
@@ -366,6 +390,13 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         return sourceMeasureCounter;
         return sourceMeasureCounter;
     }
     }
 
 
+    /**
+     * Check the Fractions for Equivalence and if so, sets maxInstrumentDuration's members accordingly.
+     * *
+     * Example: if maxInstrumentDuration = 1/1 and sourceMeasureDuration = 4/4, maxInstrumentDuration becomes 4/4.
+     * @param maxInstrumentDuration
+     * @param activeRhythm
+     */
     private checkFractionsForEquivalence(maxInstrumentDuration: Fraction, activeRhythm: Fraction): void {
     private checkFractionsForEquivalence(maxInstrumentDuration: Fraction, activeRhythm: Fraction): void {
         if (activeRhythm.Denominator > maxInstrumentDuration.Denominator) {
         if (activeRhythm.Denominator > maxInstrumentDuration.Denominator) {
             let factor: number = activeRhythm.Denominator / maxInstrumentDuration.Denominator;
             let factor: number = activeRhythm.Denominator / maxInstrumentDuration.Denominator;
@@ -373,6 +404,12 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         }
         }
     }
     }
 
 
+    /**
+     * Handle the case of an implicit [[SourceMeasure]].
+     * @param maxInstrumentDuration
+     * @param activeRhythm
+     * @returns {boolean}
+     */
     private checkIfMeasureIsImplicit(maxInstrumentDuration: Fraction, activeRhythm: Fraction): boolean {
     private checkIfMeasureIsImplicit(maxInstrumentDuration: Fraction, activeRhythm: Fraction): boolean {
         if (this.previousMeasure === undefined && maxInstrumentDuration.lt(activeRhythm)) {
         if (this.previousMeasure === undefined && maxInstrumentDuration.lt(activeRhythm)) {
             return true;
             return true;
@@ -383,6 +420,12 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         return false;
         return false;
     }
     }
 
 
+    /**
+     * Check the Duration of all the given Instruments.
+     * @param instrumentsDurations
+     * @param maxInstrumentDuration
+     * @returns {boolean}
+     */
     private allInstrumentsHaveSameDuration(instrumentsDurations: Fraction[], maxInstrumentDuration: Fraction): boolean {
     private allInstrumentsHaveSameDuration(instrumentsDurations: Fraction[], maxInstrumentDuration: Fraction): boolean {
         let counter: number = 0;
         let counter: number = 0;
         for (let idx: number = 0, len: number = instrumentsDurations.length; idx < len; ++idx) {
         for (let idx: number = 0, len: number = instrumentsDurations.length; idx < len; ++idx) {
@@ -404,7 +447,11 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         return (counter === this.currentMeasure.VerticalSourceStaffEntryContainers.length);
         return (counter === this.currentMeasure.VerticalSourceStaffEntryContainers.length);
     }
     }
 
 
-    private checkSourceMeasureForundefinedEntries(): void {
+    /**
+     * Check a [[SourceMeasure]] for possible empty / undefined entries ([[VoiceEntry]], [[SourceStaffEntry]], VerticalContainer)
+     * (caused from TieAlgorithm removing EndTieNote) and removes them if completely empty / null
+     */
+    private checkSourceMeasureForNullEntries(): void {
         for (let i: number = this.currentMeasure.VerticalSourceStaffEntryContainers.length - 1; i >= 0; i--) {
         for (let i: number = this.currentMeasure.VerticalSourceStaffEntryContainers.length - 1; i >= 0; i--) {
             for (let j: number = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries.length - 1; j >= 0; j--) {
             for (let j: number = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries.length - 1; j >= 0; j--) {
                 let sourceStaffEntry: SourceStaffEntry = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries[j];
                 let sourceStaffEntry: SourceStaffEntry = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries[j];
@@ -436,6 +483,11 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         }
         }
     }
     }
 
 
+    /**
+     * Read the XML file and creates the main sheet Labels.
+     * @param root
+     * @param filePath
+     */
     private pushSheetLabels(root: IXmlElement, filePath: string): void {
     private pushSheetLabels(root: IXmlElement, filePath: string): void {
         this.readComposer(root);
         this.readComposer(root);
         this.readTitle(root);
         this.readTitle(root);
@@ -640,6 +692,11 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         }
         }
     }
     }
 
 
+    /**
+     * Build the [[InstrumentalGroup]]s and [[Instrument]]s.
+     * @param entryList
+     * @returns {{}}
+     */
     private createInstrumentGroups(entryList: IXmlElement[]): { [_: string]: Instrument; } {
     private createInstrumentGroups(entryList: IXmlElement[]): { [_: string]: Instrument; } {
         let instrumentId: number = 0;
         let instrumentId: number = 0;
         let instrumentDict: { [_: string]: Instrument; } = {};
         let instrumentDict: { [_: string]: Instrument; } = {};
@@ -774,6 +831,11 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         return instrumentDict;
         return instrumentDict;
     }
     }
 
 
+    /**
+     * Read from each xmlInstrumentPart the first xmlMeasure in order to find out the [[Instrument]]'s number of Staves
+     * @param partInst
+     * @returns {number} - Complete number of Staves for all Instruments.
+     */
     private getCompleteNumberOfStavesFromXml(partInst: IXmlElement[]): number {
     private getCompleteNumberOfStavesFromXml(partInst: IXmlElement[]): number {
         let num: number = 0;
         let num: number = 0;
         for (let partNode of partInst) {
         for (let partNode of partInst) {
@@ -802,6 +864,11 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         return num;
         return num;
     }
     }
 
 
+    /**
+     * Read from XML for a single [[Instrument]] the first xmlMeasure in order to find out the Instrument's number of Staves.
+     * @param partNode
+     * @returns {number}
+     */
     private getInstrumentNumberOfStavesFromXml(partNode: IXmlElement): number {
     private getInstrumentNumberOfStavesFromXml(partNode: IXmlElement): number {
         let num: number = 0;
         let num: number = 0;
         let xmlMeasure: IXmlElement = partNode.element("measure");
         let xmlMeasure: IXmlElement = partNode.element("measure");
@@ -825,4 +892,5 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
         }
         }
         return num;
         return num;
     }
     }
+
 }
 }

+ 101 - 0
src/MusicalScore/ScoreIO/VoiceGenerator.ts

@@ -73,6 +73,13 @@ export class VoiceGenerator {
     public set OctaveShift(value: number) {
     public set OctaveShift(value: number) {
         this.currentOctaveShift = value;
         this.currentOctaveShift = value;
     }
     }
+
+    /**
+     * Create new [[VoiceEntry]], add it to given [[SourceStaffEntry]] and if given so, to [[Voice]].
+     * @param musicTimestamp
+     * @param parentStaffEntry
+     * @param addToVoice
+     */
     public createVoiceEntry(musicTimestamp: Fraction, parentStaffEntry: SourceStaffEntry, addToVoice: boolean): void {
     public createVoiceEntry(musicTimestamp: Fraction, parentStaffEntry: SourceStaffEntry, addToVoice: boolean): void {
         this.currentVoiceEntry = new VoiceEntry(musicTimestamp.clone(), this.voice, parentStaffEntry);
         this.currentVoiceEntry = new VoiceEntry(musicTimestamp.clone(), this.voice, parentStaffEntry);
         if (addToVoice) {
         if (addToVoice) {
@@ -82,6 +89,22 @@ export class VoiceGenerator {
             parentStaffEntry.VoiceEntries.push(this.currentVoiceEntry);
             parentStaffEntry.VoiceEntries.push(this.currentVoiceEntry);
         }
         }
     }
     }
+
+    /**
+     * Create [[Note]]s and handle Lyrics, Articulations, Beams, Ties, Slurs, Tuplets.
+     * @param noteNode
+     * @param noteDuration
+     * @param divisions
+     * @param restNote
+     * @param graceNote
+     * @param parentStaffEntry
+     * @param parentMeasure
+     * @param measureStartAbsoluteTimestamp
+     * @param maxTieNoteFraction
+     * @param chord
+     * @param guitarPro
+     * @returns {Note}
+     */
     public read(
     public read(
         noteNode: IXmlElement, noteDuration: number, divisions: number, restNote: boolean, graceNote: boolean,
         noteNode: IXmlElement, noteDuration: number, divisions: number, restNote: boolean, graceNote: boolean,
         parentStaffEntry: SourceStaffEntry, parentMeasure: SourceMeasure,
         parentStaffEntry: SourceStaffEntry, parentMeasure: SourceMeasure,
@@ -144,6 +167,11 @@ export class VoiceGenerator {
 
 
         return this.currentNote;
         return this.currentNote;
     }
     }
+
+    /**
+     * Handle the GraceNotes that appear before the Measure's End
+     * and aren't assigned to any normal (with [[VoiceEntries]]) [[SourceStaffEntry]]s yet.
+     */
     public checkForOpenGraceNotes(): void {
     public checkForOpenGraceNotes(): void {
         if (
         if (
             this.currentStaffEntry !== undefined
             this.currentStaffEntry !== undefined
@@ -174,6 +202,15 @@ export class VoiceGenerator {
             }
             }
         }
         }
     }
     }
+
+    /**
+     * Create a new [[StaffEntryLink]] and sets the currenstStaffEntry accordingly.
+     * @param index
+     * @param currentStaff
+     * @param currentStaffEntry
+     * @param currentMeasure
+     * @returns {SourceStaffEntry}
+     */
     public checkForStaffEntryLink(
     public checkForStaffEntryLink(
         index: number, currentStaff: Staff, currentStaffEntry: SourceStaffEntry, currentMeasure: SourceMeasure
         index: number, currentStaff: Staff, currentStaffEntry: SourceStaffEntry, currentMeasure: SourceMeasure
     ): SourceStaffEntry {
     ): SourceStaffEntry {
@@ -212,6 +249,12 @@ export class VoiceGenerator {
     public hasVoiceEntry(): boolean {
     public hasVoiceEntry(): boolean {
         return this.currentVoiceEntry !== undefined;
         return this.currentVoiceEntry !== undefined;
     }
     }
+
+    /**
+     *
+     * @param type
+     * @returns {Fraction} - a Note's Duration from a given type (type must be valid).
+     */
     public getNoteDurationFromType(type: string): Fraction {
     public getNoteDurationFromType(type: string): Fraction {
         switch (type) {
         switch (type) {
             case "1024th":
             case "1024th":
@@ -266,6 +309,17 @@ export class VoiceGenerator {
     //    if ((ornaNode = notationNode.element("ornaments")) !== undefined)
     //    if ((ornaNode = notationNode.element("ornaments")) !== undefined)
     //        this.articulationReader.addOrnament(ornaNode, currentVoiceEntry);
     //        this.articulationReader.addOrnament(ornaNode, currentVoiceEntry);
     //}
     //}
+
+    /**
+     * Create a new [[Note]] and adds it to the currentVoiceEntry
+     * @param node
+     * @param noteDuration
+     * @param divisions
+     * @param graceNote
+     * @param chord
+     * @param guitarPro
+     * @returns {Note}
+     */
     private addSingleNote(
     private addSingleNote(
         node: IXmlElement, noteDuration: number, divisions: number, graceNote: boolean, chord: boolean, guitarPro: boolean
         node: IXmlElement, noteDuration: number, divisions: number, graceNote: boolean, chord: boolean, guitarPro: boolean
     ): Note {
     ): Note {
@@ -355,6 +409,13 @@ export class VoiceGenerator {
         }
         }
         return note;
         return note;
     }
     }
+
+    /**
+     * Create a new rest note and add it to the currentVoiceEntry.
+     * @param noteDuration
+     * @param divisions
+     * @returns {Note}
+     */
     private addRestNote(noteDuration: number, divisions: number): Note {
     private addRestNote(noteDuration: number, divisions: number): Note {
         let restFraction: Fraction = new Fraction(noteDuration, divisions);
         let restFraction: Fraction = new Fraction(noteDuration, divisions);
         let restNote: Note = new Note(this.currentVoiceEntry, this.currentStaffEntry, restFraction, undefined);
         let restNote: Note = new Note(this.currentVoiceEntry, this.currentStaffEntry, restFraction, undefined);
@@ -364,6 +425,13 @@ export class VoiceGenerator {
         }
         }
         return restNote;
         return restNote;
     }
     }
+
+    /**
+     * Handle the currentVoiceBeam.
+     * @param node
+     * @param note
+     * @param grace
+     */
     private createBeam(node: IXmlElement, note: Note, grace: boolean): void {
     private createBeam(node: IXmlElement, note: Note, grace: boolean): void {
         try {
         try {
             let beamNode: IXmlElement = node.element("beam");
             let beamNode: IXmlElement = node.element("beam");
@@ -431,6 +499,10 @@ export class VoiceGenerator {
         }
         }
 
 
     }
     }
+
+    /**
+     * Check for open [[Beam]]s at end of [[SourceMeasure]] and closes them explicity.
+     */
     private handleOpenBeam(): void {
     private handleOpenBeam(): void {
         if (this.openBeam.Notes.length === 1) {
         if (this.openBeam.Notes.length === 1) {
             let beamNote: Note = this.openBeam.Notes[0];
             let beamNote: Note = this.openBeam.Notes[0];
@@ -520,6 +592,13 @@ export class VoiceGenerator {
             note.ParentVoiceEntry = graceVoiceEntry;
             note.ParentVoiceEntry = graceVoiceEntry;
         }
         }
     }
     }
+
+    /**
+     * Create a [[Tuplet]].
+     * @param node
+     * @param tupletNodeList
+     * @returns {number}
+     */
     private addTuplet(node: IXmlElement, tupletNodeList: IXmlElement[]): number {
     private addTuplet(node: IXmlElement, tupletNodeList: IXmlElement[]): number {
         if (tupletNodeList !== undefined && tupletNodeList.length > 1) {
         if (tupletNodeList !== undefined && tupletNodeList.length > 1) {
             let timeModNode: IXmlElement = node.element("time-modification");
             let timeModNode: IXmlElement = node.element("time-modification");
@@ -650,6 +729,11 @@ export class VoiceGenerator {
         }
         }
         return this.openTupletNumber;
         return this.openTupletNumber;
     }
     }
+
+    /**
+     * Handle the time-modification [[IXmlElement]] for the [[Tuplet]] case (tupletNotes not at begin/end of [[Tuplet]]).
+     * @param noteNode
+     */
     private handleTimeModificationNode(noteNode: IXmlElement): void {
     private handleTimeModificationNode(noteNode: IXmlElement): void {
         if (this.openTupletNumber in this.tupletDict) {
         if (this.openTupletNumber in this.tupletDict) {
             try {
             try {
@@ -825,6 +909,11 @@ export class VoiceGenerator {
             }
             }
         }
         }
     }
     }
+
+    /**
+     * Find the next free int (starting from 0) to use as key in TieDict.
+     * @returns {number}
+     */
     private getNextAvailableNumberForTie(): number {
     private getNextAvailableNumberForTie(): number {
         let keys: string[] = Object.keys(this.openTieDict);
         let keys: string[] = Object.keys(this.openTieDict);
         if (keys.length === 0) { return 1; }
         if (keys.length === 0) { return 1; }
@@ -836,6 +925,12 @@ export class VoiceGenerator {
         }
         }
         return +(keys[keys.length - 1]) + 1;
         return +(keys[keys.length - 1]) + 1;
     }
     }
+
+    /**
+     * Search the tieDictionary for the corresponding candidateNote to the currentNote (same FundamentalNote && Octave).
+     * @param candidateNote
+     * @returns {number}
+     */
     private findCurrentNoteInTieDict(candidateNote: Note): number {
     private findCurrentNoteInTieDict(candidateNote: Note): number {
         let openTieDict: { [_: number]: Tie; } = this.openTieDict;
         let openTieDict: { [_: number]: Tie; } = this.openTieDict;
         for (let key in openTieDict) {
         for (let key in openTieDict) {
@@ -848,6 +943,12 @@ export class VoiceGenerator {
         }
         }
         return -1;
         return -1;
     }
     }
+
+    /**
+     * Calculate the normal duration of a [[Tuplet]] note.
+     * @param xmlNode
+     * @returns {any}
+     */
     private getTupletNoteDurationFromType(xmlNode: IXmlElement): Fraction {
     private getTupletNoteDurationFromType(xmlNode: IXmlElement): Fraction {
         if (xmlNode.element("type") !== undefined) {
         if (xmlNode.element("type") !== undefined) {
             let typeNode: IXmlElement = xmlNode.element("type");
             let typeNode: IXmlElement = xmlNode.element("type");

+ 3 - 1
src/MusicalScore/VoiceData/Beam.ts

@@ -1,9 +1,10 @@
 import {Note} from "./Note";
 import {Note} from "./Note";
 
 
 /**
 /**
- * A beam - the bar grouping multiple consecutive [[Note]]s.
+ * A [[Beam]] - the bar grouping multiple consecutive [[Note]]s.
  */
  */
 export class Beam {
 export class Beam {
+
     private notes: Note[] = [];
     private notes: Note[] = [];
     private extendedNoteList: Note[] = [];
     private extendedNoteList: Note[] = [];
 
 
@@ -31,6 +32,7 @@ export class Beam {
             this.extendedNoteList.push(note);
             this.extendedNoteList.push(note);
         }
         }
     }
     }
+
 }
 }
 
 
 export enum BeamEnum {
 export enum BeamEnum {

+ 2 - 0
src/MusicalScore/VoiceData/Expressions/AbstractTempoExpression.ts

@@ -2,6 +2,7 @@ import {PlacementEnum} from "./AbstractExpression";
 import {MultiTempoExpression} from "./MultiTempoExpression";
 import {MultiTempoExpression} from "./MultiTempoExpression";
 
 
 export abstract class AbstractTempoExpression {
 export abstract class AbstractTempoExpression {
+
     constructor(label: string, placement: PlacementEnum, staffNumber: number, parentMultiTempoExpression: MultiTempoExpression) {
     constructor(label: string, placement: PlacementEnum, staffNumber: number, parentMultiTempoExpression: MultiTempoExpression) {
         this.label = label;
         this.label = label;
         this.placement = placement;
         this.placement = placement;
@@ -47,4 +48,5 @@ export abstract class AbstractTempoExpression {
     private static stringContainsSeparatedWord(str: string, word: string): boolean {
     private static stringContainsSeparatedWord(str: string, word: string): boolean {
         return (str === word || str.indexOf(" " + word) !== -1 || str.indexOf(word + " ") !== -1);
         return (str === word || str.indexOf(" " + word) !== -1 || str.indexOf(word + " ") !== -1);
     }
     }
+
 }
 }

+ 3 - 0
src/MusicalScore/VoiceData/Expressions/MultiExpression.ts

@@ -9,10 +9,12 @@ import {AbstractExpression} from "./AbstractExpression";
 import {PlacementEnum} from "./AbstractExpression";
 import {PlacementEnum} from "./AbstractExpression";
 
 
 export class MultiExpression /*implements IComparable<MultiExpression>*/ {
 export class MultiExpression /*implements IComparable<MultiExpression>*/ {
+
     constructor(sourceMeasure: SourceMeasure, timestamp: Fraction) {
     constructor(sourceMeasure: SourceMeasure, timestamp: Fraction) {
         this.sourceMeasure = sourceMeasure;
         this.sourceMeasure = sourceMeasure;
         this.timestamp = timestamp;
         this.timestamp = timestamp;
     }
     }
+
     private sourceMeasure: SourceMeasure;
     private sourceMeasure: SourceMeasure;
     private staffNumber: number;
     private staffNumber: number;
     private timestamp: Fraction;
     private timestamp: Fraction;
@@ -191,6 +193,7 @@ export class MultiExpression /*implements IComparable<MultiExpression>*/ {
             }
             }
         }
         }
     }
     }
+
 }
 }
 
 
 export class MultiExpressionEntry {
 export class MultiExpressionEntry {

+ 1 - 0
src/MusicalScore/VoiceData/Expressions/MultiTempoExpression.ts

@@ -7,6 +7,7 @@ import {AbstractTempoExpression} from "./AbstractTempoExpression";
 import {ContinuousTempoExpression} from "./ContinuousExpressions/ContinuousTempoExpression";
 import {ContinuousTempoExpression} from "./ContinuousExpressions/ContinuousTempoExpression";
 
 
 export class MultiTempoExpression /*implements IComparable<MultiTempoExpression>*/ {
 export class MultiTempoExpression /*implements IComparable<MultiTempoExpression>*/ {
+
     constructor(sourceMeasure: SourceMeasure, timestamp: Fraction) {
     constructor(sourceMeasure: SourceMeasure, timestamp: Fraction) {
         this.sourceMeasure = sourceMeasure;
         this.sourceMeasure = sourceMeasure;
         this.timestamp = timestamp;
         this.timestamp = timestamp;

+ 4 - 0
src/MusicalScore/VoiceData/Instructions/AbstractNotationInstruction.ts

@@ -1,14 +1,18 @@
 import {SourceStaffEntry} from "../SourceStaffEntry";
 import {SourceStaffEntry} from "../SourceStaffEntry";
 
 
 export abstract class AbstractNotationInstruction {
 export abstract class AbstractNotationInstruction {
+
     constructor(parent: SourceStaffEntry) {
     constructor(parent: SourceStaffEntry) {
         this.parent = parent;
         this.parent = parent;
     }
     }
+
     protected parent: SourceStaffEntry;
     protected parent: SourceStaffEntry;
+
     public get Parent(): SourceStaffEntry {
     public get Parent(): SourceStaffEntry {
         return this.parent;
         return this.parent;
     }
     }
     public set Parent(value: SourceStaffEntry) {
     public set Parent(value: SourceStaffEntry) {
         this.parent = value;
         this.parent = value;
     }
     }
+
 }
 }

+ 3 - 0
src/MusicalScore/VoiceData/Instructions/ClefInstruction.ts

@@ -4,6 +4,9 @@ import {NoteEnum} from "../../../Common/DataObjects/Pitch";
 import {AccidentalEnum} from "../../../Common/DataObjects/Pitch";
 import {AccidentalEnum} from "../../../Common/DataObjects/Pitch";
 import {ArgumentOutOfRangeException} from "../../Exceptions";
 import {ArgumentOutOfRangeException} from "../../Exceptions";
 
 
+/**
+ * A [[ClefInstruction]] is the clef placed at the beginning of the stave, which indicates the pitch of the notes.
+ */
 export class ClefInstruction extends AbstractNotationInstruction {
 export class ClefInstruction extends AbstractNotationInstruction {
     constructor(clefType: ClefEnum = ClefEnum.G, octaveOffset: number = 0, line: number = 2) {
     constructor(clefType: ClefEnum = ClefEnum.G, octaveOffset: number = 0, line: number = 2) {
         super(undefined); // FIXME? Missing SourceStaffEntry!
         super(undefined); // FIXME? Missing SourceStaffEntry!

+ 3 - 1
src/MusicalScore/VoiceData/Instructions/KeyInstruction.ts

@@ -4,7 +4,9 @@ import {NoteEnum} from "../../../Common/DataObjects/Pitch";
 import {AccidentalEnum} from "../../../Common/DataObjects/Pitch";
 import {AccidentalEnum} from "../../../Common/DataObjects/Pitch";
 import {Pitch} from "../../../Common/DataObjects/Pitch";
 import {Pitch} from "../../../Common/DataObjects/Pitch";
 
 
-
+/**
+ * A [[KeyInstruction]] is a key signature denoting which notes are to be sharpened or flattened.
+ */
 export class KeyInstruction extends AbstractNotationInstruction {
 export class KeyInstruction extends AbstractNotationInstruction {
     constructor(sourceStaffEntry: SourceStaffEntry = undefined, key: number = 0, mode: KeyEnum = KeyEnum.major) {
     constructor(sourceStaffEntry: SourceStaffEntry = undefined, key: number = 0, mode: KeyEnum = KeyEnum.major) {
         super(sourceStaffEntry);
         super(sourceStaffEntry);

+ 3 - 0
src/MusicalScore/VoiceData/Instructions/RhythmInstruction.ts

@@ -1,6 +1,9 @@
 import {AbstractNotationInstruction} from "./AbstractNotationInstruction";
 import {AbstractNotationInstruction} from "./AbstractNotationInstruction";
 import {Fraction} from "../../../Common/DataObjects/Fraction";
 import {Fraction} from "../../../Common/DataObjects/Fraction";
 
 
+/**
+ * A [[RhythmInstruction]] is the time signature which specifies the number of beats in each bar, and the value of one beat.
+ */
 export class RhythmInstruction extends AbstractNotationInstruction {
 export class RhythmInstruction extends AbstractNotationInstruction {
     constructor(rhythm: Fraction, numerator: number, denominator: number, rhythmSymbolEnum: RhythmSymbolEnum) {
     constructor(rhythm: Fraction, numerator: number, denominator: number, rhythmSymbolEnum: RhythmSymbolEnum) {
         super(undefined); // FIXME no parent SourceStaffEntry
         super(undefined); // FIXME no parent SourceStaffEntry