Просмотр исходного кода

fix(tuplet): fix duplet, quadruplet, tuplet layout

vexflow previously didn't get a reasonable notesOccupied (how many normal notes the tuplet replaces).
fix #488
sschmid 6 лет назад
Родитель
Сommit
596e794f85

+ 1 - 1
src/MusicalScore/Graphical/VexFlow/VexFlowMeasure.ts

@@ -727,8 +727,8 @@ export class VexFlowMeasure extends GraphicalMeasure {
                       tupletStaveNotes.push(((tupletVoiceEntry).vfStaveNote as StaveNote));
                     }
                     if (tupletStaveNotes.length > 1) {
-                      const notesOccupied: number = 2;
                       const tuplet: Tuplet = tupletBuilder[0];
+                      const notesOccupied: number = tuplet.Notes[0][0].NormalNotes;
                       const bracketed: boolean = tuplet.Bracket ||
                         (tuplet.TupletLabelNumber === 3 && EngravingRules.Rules.TripletsBracketed) ||
                         (tuplet.TupletLabelNumber !== 3 && EngravingRules.Rules.TupletsBracketed);

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

@@ -164,6 +164,7 @@ export class InstrumentReader {
           }
           let noteDivisions: number = 0;
           let noteDuration: Fraction = new Fraction(0, 1);
+          let normalNotes: number = 2;
           let typeDuration: Fraction = undefined;
           let isTuplet: boolean = false;
           if (xmlNode.element("duration") !== undefined) {
@@ -177,6 +178,12 @@ export class InstrumentReader {
               }
               if (xmlNode.element("time-modification") !== undefined) {
                 noteDuration = this.getNoteDurationForTuplet(xmlNode);
+                const time: IXmlElement = xmlNode.element("time-modification");
+                if (time !== undefined) {
+                  if (time.element("normal-notes") !== undefined) {
+                    normalNotes = parseInt(time.element("normal-notes").value, 10);
+                  }
+                }
                 isTuplet = true;
               }
             } else {
@@ -332,7 +339,7 @@ export class InstrumentReader {
             noteDuration = new Fraction(noteDivisions, 4 * this.divisions);
           }
           this.currentVoiceGenerator.read(
-            xmlNode, noteDuration, typeDuration, restNote,
+            xmlNode, noteDuration, typeDuration, normalNotes, restNote,
             this.currentStaffEntry, this.currentMeasure,
             measureStartAbsoluteTimestamp,
             this.maxTieNoteFraction, isChord, guitarPro,

+ 4 - 3
src/MusicalScore/ScoreIO/VoiceGenerator.ts

@@ -103,7 +103,7 @@ export class VoiceGenerator {
    * @param printObject whether the note should be rendered (true) or invisible (false)
    * @returns {Note}
    */
-  public read(noteNode: IXmlElement, noteDuration: Fraction, typeDuration: Fraction, restNote: boolean,
+  public read(noteNode: IXmlElement, noteDuration: Fraction, typeDuration: Fraction, normalNotes: number, restNote: boolean,
               parentStaffEntry: SourceStaffEntry, parentMeasure: SourceMeasure,
               measureStartAbsoluteTimestamp: Fraction, maxTieNoteFraction: Fraction, chord: boolean, guitarPro: boolean,
               printObject: boolean, isCueNote: boolean, stemDirectionXml: StemDirectionType,
@@ -114,7 +114,7 @@ export class VoiceGenerator {
     try {
       this.currentNote = restNote
         ? this.addRestNote(noteDuration, printObject, isCueNote, noteheadColorXml)
-        : this.addSingleNote(noteNode, noteDuration, typeDuration, chord, guitarPro,
+        : this.addSingleNote(noteNode, noteDuration, typeDuration, normalNotes, chord, guitarPro,
                              printObject, isCueNote, stemDirectionXml, stemColorXml, noteheadColorXml);
       // read lyrics
       const lyricElements: IXmlElement[] = noteNode.elements("lyric");
@@ -322,7 +322,7 @@ export class VoiceGenerator {
    * @param guitarPro
    * @returns {Note}
    */
-  private addSingleNote(node: IXmlElement, noteDuration: Fraction, typeDuration: Fraction, chord: boolean, guitarPro: boolean,
+  private addSingleNote(node: IXmlElement, noteDuration: Fraction, typeDuration: Fraction, normalNotes: number, chord: boolean, guitarPro: boolean,
                         printObject: boolean, isCueNote: boolean, stemDirectionXml: StemDirectionType,
                         stemColorXml: string, noteheadColorXml: string): Note {
     //log.debug("addSingleNote called");
@@ -417,6 +417,7 @@ export class VoiceGenerator {
     const noteLength: Fraction = Fraction.createFromFraction(noteDuration);
     const note: Note = new Note(this.currentVoiceEntry, this.currentStaffEntry, noteLength, pitch);
     note.TypeLength = typeDuration;
+    note.NormalNotes = normalNotes;
     note.PrintObject = printObject;
     note.IsCueNote = isCueNote;
     note.StemDirectionXml = stemDirectionXml; // maybe unnecessary, also in VoiceEntry

+ 8 - 0
src/MusicalScore/VoiceData/Note.ts

@@ -38,6 +38,8 @@ export class Note {
     private length: Fraction;
     /** The length/duration given in the <type> tag. different from length for tuplets/tremolos. */
     private typeLength: Fraction;
+    /** The amount of notes the tuplet of this note (if there is one) replaces. */
+    private normalNotes: number;
     /**
      * The untransposed (!!!) source data.
      */
@@ -98,6 +100,12 @@ export class Note {
     public set TypeLength(value: Fraction) {
         this.typeLength = value;
     }
+    public get NormalNotes(): number {
+        return this.normalNotes;
+    }
+    public set NormalNotes(value: number) {
+        this.normalNotes = value;
+    }
     public get Pitch(): Pitch {
         return this.pitch;
     }

+ 2 - 1
src/MusicalScore/VoiceData/Tuplet.ts

@@ -12,7 +12,8 @@ export class Tuplet {
     }
 
     private tupletLabelNumber: number;
-    private notes: Note[][] = [];
+    /** Notes contained in the tuplet, per VoiceEntry (list of VoiceEntries, which has a list of notes). */
+    private notes: Note[][] = []; // TODO should probably be VoiceEntry[], not Note[][].
     private fractions: Fraction[] = [];
     /** Whether this tuplet has a bracket. (e.g. showing |--3--| or just 3 for a triplet) */
     private bracket: boolean;