Selaa lähdekoodia

refactor(GraceNotes): remove some special case handling of grace notes

remove function VoiceGenerator.handleGraceNote()
move graceNoteSlash handling from handleGraceNote() to InstrumentReader

part of #56
sschmidTU 7 vuotta sitten
vanhempi
commit
2fe01dae5b

+ 21 - 4
src/MusicalScore/ScoreIO/InstrumentReader.ts

@@ -179,7 +179,21 @@ export class InstrumentReader {
 
 
           const restNote: boolean = xmlNode.element("rest") !== undefined;
           const restNote: boolean = xmlNode.element("rest") !== undefined;
           //log.info("New note found!", noteDivisions, noteDuration.toString(), restNote);
           //log.info("New note found!", noteDivisions, noteDuration.toString(), restNote);
+
           const isGraceNote: boolean = xmlNode.element("grace") !== undefined || noteDivisions === 0 || isChord && lastNoteWasGrace;
           const isGraceNote: boolean = xmlNode.element("grace") !== undefined || noteDivisions === 0 || isChord && lastNoteWasGrace;
+          let graceNoteSlash: boolean = false;
+          if (isGraceNote) {
+            const graceNode: IXmlElement = xmlNode.element("grace");
+            if (graceNode && graceNode.attributes()) {
+              if (graceNode.attribute("slash")) {
+                const slash: string = graceNode.attribute("slash").value;
+                if (slash === "yes") {
+                  graceNoteSlash = true;
+                }
+              }
+            }
+          }
+
           let musicTimestamp: Fraction = currentFraction.clone();
           let musicTimestamp: Fraction = currentFraction.clone();
           if (isChord) {
           if (isChord) {
             musicTimestamp = previousFraction.clone();
             musicTimestamp = previousFraction.clone();
@@ -191,8 +205,11 @@ export class InstrumentReader {
           ).staffEntry;
           ).staffEntry;
           //log.info("currentStaffEntry", this.currentStaffEntry, this.currentMeasure.VerticalSourceStaffEntryContainers.length);
           //log.info("currentStaffEntry", this.currentStaffEntry, this.currentMeasure.VerticalSourceStaffEntryContainers.length);
 
 
-          if (!this.currentVoiceGenerator.hasVoiceEntry() || (!isChord && !isGraceNote && !lastNoteWasGrace) || (!lastNoteWasGrace && isGraceNote)) {
-            this.currentVoiceGenerator.createVoiceEntry(musicTimestamp, this.currentStaffEntry, !restNote, isGraceNote);
+          if (!this.currentVoiceGenerator.hasVoiceEntry()
+            || (!isChord && !isGraceNote && !lastNoteWasGrace)
+            || (isGraceNote && !lastNoteWasGrace)
+          ) {
+            this.currentVoiceGenerator.createVoiceEntry(musicTimestamp, this.currentStaffEntry, !restNote, isGraceNote, graceNoteSlash);
           }
           }
           if (!isGraceNote && !isChord) {
           if (!isGraceNote && !isChord) {
             previousFraction = currentFraction.clone();
             previousFraction = currentFraction.clone();
@@ -222,7 +239,7 @@ export class InstrumentReader {
           }
           }
           if (isTuplet) {
           if (isTuplet) {
             this.currentVoiceGenerator.read(
             this.currentVoiceGenerator.read(
-              xmlNode, noteDuration, restNote, isGraceNote,
+              xmlNode, noteDuration, restNote,
               this.currentStaffEntry, this.currentMeasure,
               this.currentStaffEntry, this.currentMeasure,
               measureStartAbsoluteTimestamp,
               measureStartAbsoluteTimestamp,
               this.maxTieNoteFraction, isChord, guitarPro
               this.maxTieNoteFraction, isChord, guitarPro
@@ -230,7 +247,7 @@ export class InstrumentReader {
           } else {
           } else {
             this.currentVoiceGenerator.read(
             this.currentVoiceGenerator.read(
               xmlNode, new Fraction(noteDivisions, 4 * this.divisions),
               xmlNode, new Fraction(noteDivisions, 4 * this.divisions),
-              restNote, isGraceNote, this.currentStaffEntry,
+              restNote, this.currentStaffEntry,
               this.currentMeasure, measureStartAbsoluteTimestamp,
               this.currentMeasure, measureStartAbsoluteTimestamp,
               this.maxTieNoteFraction, isChord, guitarPro
               this.maxTieNoteFraction, isChord, guitarPro
             );
             );

+ 7 - 69
src/MusicalScore/ScoreIO/VoiceGenerator.ts

@@ -79,7 +79,8 @@ export class VoiceGenerator {
    * @param addToVoice
    * @param addToVoice
    * @param isGrace States whether the new VoiceEntry (only) has grace notes
    * @param isGrace States whether the new VoiceEntry (only) has grace notes
    */
    */
-  public createVoiceEntry(musicTimestamp: Fraction, parentStaffEntry: SourceStaffEntry, addToVoice: boolean, isGrace: boolean = false): void {
+  public createVoiceEntry(musicTimestamp: Fraction, parentStaffEntry: SourceStaffEntry, addToVoice: boolean,
+                          isGrace: boolean = false, graceNoteSlash: boolean = false): void {
     this.currentVoiceEntry = new VoiceEntry(musicTimestamp.clone(), this.voice, parentStaffEntry, isGrace);
     this.currentVoiceEntry = new VoiceEntry(musicTimestamp.clone(), this.voice, parentStaffEntry, isGrace);
     if (addToVoice) {
     if (addToVoice) {
       this.voice.VoiceEntries.push(this.currentVoiceEntry);
       this.voice.VoiceEntries.push(this.currentVoiceEntry);
@@ -95,7 +96,6 @@ export class VoiceGenerator {
    * @param noteDuration
    * @param noteDuration
    * @param divisions
    * @param divisions
    * @param restNote
    * @param restNote
-   * @param graceNote
    * @param parentStaffEntry
    * @param parentStaffEntry
    * @param parentMeasure
    * @param parentMeasure
    * @param measureStartAbsoluteTimestamp
    * @param measureStartAbsoluteTimestamp
@@ -104,7 +104,7 @@ export class VoiceGenerator {
    * @param guitarPro
    * @param guitarPro
    * @returns {Note}
    * @returns {Note}
    */
    */
-  public read(noteNode: IXmlElement, noteDuration: Fraction, restNote: boolean, graceNote: boolean,
+  public read(noteNode: IXmlElement, noteDuration: Fraction, restNote: boolean,
               parentStaffEntry: SourceStaffEntry, parentMeasure: SourceMeasure,
               parentStaffEntry: SourceStaffEntry, parentMeasure: SourceMeasure,
               measureStartAbsoluteTimestamp: Fraction, maxTieNoteFraction: Fraction, chord: boolean, guitarPro: boolean): Note {
               measureStartAbsoluteTimestamp: Fraction, maxTieNoteFraction: Fraction, chord: boolean, guitarPro: boolean): Note {
     this.currentStaffEntry = parentStaffEntry;
     this.currentStaffEntry = parentStaffEntry;
@@ -113,7 +113,7 @@ export class VoiceGenerator {
     try {
     try {
       this.currentNote = restNote
       this.currentNote = restNote
         ? this.addRestNote(noteDuration)
         ? this.addRestNote(noteDuration)
-        : this.addSingleNote(noteNode, noteDuration, graceNote, chord, guitarPro);
+        : this.addSingleNote(noteNode, noteDuration, chord, guitarPro);
 
 
       if (this.lyricsReader !== undefined && noteNode.elements("lyric") !== undefined) {
       if (this.lyricsReader !== undefined && noteNode.elements("lyric") !== undefined) {
         this.lyricsReader.addLyricEntry(noteNode.elements("lyric"), this.currentVoiceEntry);
         this.lyricsReader.addLyricEntry(noteNode.elements("lyric"), this.currentVoiceEntry);
@@ -138,7 +138,7 @@ export class VoiceGenerator {
           hasTupletCommand = true;
           hasTupletCommand = true;
         }
         }
         // check for Arpeggios
         // check for Arpeggios
-        if (notationNode.element("arpeggiate") !== undefined && !graceNote) {
+        if (notationNode.element("arpeggiate") !== undefined && !this.currentVoiceEntry.IsGrace) {
           this.currentVoiceEntry.ArpeggiosNotesIndices.push(this.currentVoiceEntry.Notes.indexOf(this.currentNote));
           this.currentVoiceEntry.ArpeggiosNotesIndices.push(this.currentVoiceEntry.Notes.indexOf(this.currentNote));
         }
         }
         // check for Ties - must be the last check
         // check for Ties - must be the last check
@@ -290,12 +290,11 @@ export class VoiceGenerator {
    * @param node
    * @param node
    * @param noteDuration
    * @param noteDuration
    * @param divisions
    * @param divisions
-   * @param graceNote
    * @param chord
    * @param chord
    * @param guitarPro
    * @param guitarPro
    * @returns {Note}
    * @returns {Note}
    */
    */
-  private addSingleNote(node: IXmlElement, noteDuration: Fraction, graceNote: boolean, chord: boolean, guitarPro: boolean): Note {
+  private addSingleNote(node: IXmlElement, noteDuration: Fraction, chord: boolean, guitarPro: boolean): Note {
     //log.debug("addSingleNote called");
     //log.debug("addSingleNote called");
     let noteAlter: AccidentalEnum = AccidentalEnum.NONE;
     let noteAlter: AccidentalEnum = AccidentalEnum.NONE;
     let noteStep: NoteEnum = NoteEnum.C;
     let noteStep: NoteEnum = NoteEnum.C;
@@ -372,11 +371,7 @@ export class VoiceGenerator {
     const noteLength: Fraction = Fraction.createFromFraction(noteDuration);
     const noteLength: Fraction = Fraction.createFromFraction(noteDuration);
     const note: Note = new Note(this.currentVoiceEntry, this.currentStaffEntry, noteLength, pitch);
     const note: Note = new Note(this.currentVoiceEntry, this.currentStaffEntry, noteLength, pitch);
     note.PlaybackInstrumentId = playbackInstrumentId;
     note.PlaybackInstrumentId = playbackInstrumentId;
-    if (!graceNote) {
-      this.currentVoiceEntry.Notes.push(note);
-    } else {
-      this.handleGraceNote(node, note);
-    }
+    this.currentVoiceEntry.Notes.push(note);
     if (node.elements("beam") && !chord) {
     if (node.elements("beam") && !chord) {
       this.createBeam(node, note);
       this.createBeam(node, note);
     }
     }
@@ -493,63 +488,6 @@ export class VoiceGenerator {
     }
     }
   }
   }
 
 
-  private handleGraceNote(node: IXmlElement, note: Note): void {
-    let graceChord: boolean = false;
-    let type: string = "";
-    if (node.elements("type")) {
-      const typeNode: IXmlElement[] = node.elements("type");
-      if (typeNode) {
-        type = typeNode[0].value;
-        try {
-          note.Length = this.getNoteDurationFromType(type);
-          note.Length.Numerator = 1;
-        } catch (e) {
-          const errorMsg: string = ITextTranslation.translateText(
-            "ReaderErrorMessages/NoteDurationError", "Invalid note duration."
-          );
-          this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-          throw new MusicSheetReadingException(errorMsg, e);
-        }
-
-      }
-    }
-    const graceNode: IXmlElement = node.element("grace");
-    let graceNoteSlash: boolean = false;
-    // TODO overlap with InstrumentReader.readNextXmlMeasure, which also checks whether there's a grace node in XML
-    if (graceNode !== undefined && graceNode.attributes()) {
-      if (graceNode.attribute("slash")) {
-        const slash: string = graceNode.attribute("slash").value;
-        if (slash === "yes") {
-          graceNoteSlash = true;
-        }
-      }
-    }
-    if (node.element("chord") !== undefined) {
-      graceChord = true;
-    }
-    let graceVoiceEntry: VoiceEntry = undefined;
-    if (!graceChord) {
-      graceVoiceEntry = new VoiceEntry(
-        new Fraction(0, 1), this.currentVoiceEntry.ParentVoice, this.currentStaffEntry, true, graceNoteSlash
-      );
-      if (this.currentVoiceEntry.graceVoiceEntriesBefore === undefined) {
-        this.currentVoiceEntry.graceVoiceEntriesBefore = [];
-      }
-      this.currentVoiceEntry.graceVoiceEntriesBefore.push(graceVoiceEntry);
-    } else {
-      if (
-        this.currentVoiceEntry.graceVoiceEntriesBefore !== undefined
-        && this.currentVoiceEntry.graceVoiceEntriesBefore.length > 0
-      ) {
-        graceVoiceEntry = CollectionUtil.last(this.currentVoiceEntry.graceVoiceEntriesBefore);
-      }
-    }
-    if (graceVoiceEntry !== undefined) {
-      graceVoiceEntry.Notes.push(note);
-      note.ParentVoiceEntry = graceVoiceEntry;
-    }
-  }
-
   /**
   /**
    * Create a [[Tuplet]].
    * Create a [[Tuplet]].
    * @param node
    * @param node