Forráskód Böngészése

PercussionOneLineXML position: fix occasional wrong octave (#945), add sample

sschmid 4 éve
szülő
commit
2907aa8fdc

+ 7 - 2
src/Common/DataObjects/Pitch.ts

@@ -69,14 +69,19 @@ export class Pitch {
     /** This method goes x steps from a NoteEnum on a keyboard.
      * E.g. Two steps to the left (-2) from a D is a B.
      * Two steps to the right from an A is a C. */
-    public static stepFromNoteEnum(noteEnum: NoteEnum, step: number): NoteEnum {
+    public static stepFromNoteEnum(noteEnum: NoteEnum, step: number): [NoteEnum, number] {
         const enums: NoteEnum[] = Pitch.pitchEnumValues;
         const originalIndex: number = enums.indexOf(noteEnum);
+        let octaveShift: number = 0;
         let newIndex: number = originalIndex + step % enums.length; // modulo only handles positive overflow
+        if (originalIndex + step > enums.length - 1) {
+            octaveShift = 1;
+        }
         if (newIndex < 0) {
             newIndex = enums.length + newIndex; // handle underflow, e.g. - 1: enums.length + (-1) = last element
+            octaveShift = -1;
         }
-        return enums[newIndex];
+        return [enums[newIndex], octaveShift];
     }
 
     /**

+ 45 - 42
src/MusicalScore/Graphical/VexFlow/VexflowStafflineNoteCalculator.ts

@@ -89,8 +89,9 @@ export class VexflowStafflineNoteCalculator implements IStafflineNoteCalculator
             return graphicalNote;
         }
         const currentPitchList: Array<Pitch> = this.staffPitchListMapping.getValue(staffIndex);
-        //Don't need to position notes. We aren't under the cutoff
-        if (currentPitchList.length > this.rules.PercussionOneLineCutoff) {
+        const positionByXml: boolean = this.rules.PercussionOneLineUseXMLDisplayStep && graphicalNote.sourceNote.displayStepUnpitched !== undefined;
+        if (currentPitchList.length > this.rules.PercussionOneLineCutoff && !positionByXml) {
+            //Don't need to position notes. We aren't under the cutoff
             return graphicalNote;
         }
         const vfGraphicalNote: VexFlowGraphicalNote = graphicalNote as VexFlowGraphicalNote;
@@ -115,46 +116,48 @@ export class VexflowStafflineNoteCalculator implements IStafflineNoteCalculator
                     displayOctave = graphicalNote.sourceNote.displayOctaveUnpitched + this.rules.PercussionOneLineXMLDisplayStepOctaveOffset;
                 }
                 const half: number = Math.ceil(currentPitchList.length / 2);
-                //position above
-                if (pitchIndex >= half && !this.rules.PercussionOneLineUseXMLDisplayStep) {
-                    displayOctave = 2;
-                    switch ((pitchIndex - half) % 5) {
-                        case 1:
-                            displayNote = NoteEnum.E;
-                            break;
-                        case 2:
-                            displayNote = NoteEnum.G;
-                            break;
-                        case 3:
-                            displayNote = NoteEnum.B;
-                            break;
-                        case 4:
-                            displayNote = NoteEnum.D;
-                            displayOctave = 3;
-                            break;
-                        default:
-                            displayNote = NoteEnum.C;
-                            break;
-                    }
-                } else if (!this.rules.PercussionOneLineUseXMLDisplayStep) { //position below
-                    switch (pitchIndex % 5) {
-                        case 1:
-                            displayNote = NoteEnum.F;
-                            break;
-                        case 2:
-                            displayNote = NoteEnum.D;
-                            break;
-                        case 3:
-                            displayNote = NoteEnum.B;
-                            displayOctave = 0;
-                            break;
-                        case 4:
-                            displayNote = NoteEnum.G;
-                            displayOctave = 0;
-                            break;
-                        default:
-                            displayNote = NoteEnum.A;
-                            break;
+                if (!this.rules.PercussionOneLineUseXMLDisplayStep) {
+                    if (pitchIndex >= half) {
+                        //position above
+                        displayOctave = 2;
+                        switch ((pitchIndex - half) % 5) {
+                            case 1:
+                                displayNote = NoteEnum.E;
+                                break;
+                            case 2:
+                                displayNote = NoteEnum.G;
+                                break;
+                            case 3:
+                                displayNote = NoteEnum.B;
+                                break;
+                            case 4:
+                                displayNote = NoteEnum.D;
+                                displayOctave = 3;
+                                break;
+                            default:
+                                displayNote = NoteEnum.C;
+                                break;
+                        }
+                    } else { //position below
+                        switch (pitchIndex % 5) {
+                            case 1:
+                                displayNote = NoteEnum.F;
+                                break;
+                            case 2:
+                                displayNote = NoteEnum.D;
+                                break;
+                            case 3:
+                                displayNote = NoteEnum.B;
+                                displayOctave = 0;
+                                break;
+                            case 4:
+                                displayNote = NoteEnum.G;
+                                displayOctave = 0;
+                                break;
+                            default:
+                                displayNote = NoteEnum.A;
+                                break;
+                        }
                     }
                 }
                 const mappedPitch: Pitch = new Pitch(displayNote, displayOctave, notePitch.Accidental);

+ 8 - 5
src/MusicalScore/ScoreIO/VoiceGenerator.ts

@@ -384,18 +384,21 @@ export class VoiceGenerator {
           }
         } else if (noteElement.name === "unpitched") {
           const displayStepElement: IXmlElement = noteElement.element("display-step");
-          if (displayStepElement) {
-            noteStep = NoteEnum[displayStepElement.value.toUpperCase()];
-            displayStepUnpitched = Pitch.stepFromNoteEnum(noteStep, -3);
-          }
           const octave: IXmlElement = noteElement.element("display-octave");
           if (octave) {
             noteOctave = parseInt(octave.value, 10);
-            displayOctaveUnpitched = noteOctave - 3;
+            displayOctaveUnpitched = noteOctave - 2;
             if (guitarPro) {
               noteOctave += 1;
             }
           }
+          if (displayStepElement) {
+            noteStep = NoteEnum[displayStepElement.value.toUpperCase()];
+            let octaveShift: number = 0;
+            [displayStepUnpitched, octaveShift] = Pitch.stepFromNoteEnum(noteStep, -3);
+            console.log("octaveshift2: " + octaveShift);
+            displayOctaveUnpitched += octaveShift;
+          }
         } else if (noteElement.name === "instrument") {
           if (noteElement.firstAttribute) {
             playbackInstrumentId = noteElement.firstAttribute.value;

+ 247 - 0
test/data/test_percussiononelineusexmldisplaystep_octave.musicxml

@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding='UTF-8' standalone='no' ?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise version="3.0">
+ <work>
+  <work-title>Test - PercussionOneLineUseXMLDisplayStep Octave</work-title>
+ </work>
+ <identification>
+  <encoding>
+   <encoding-date>2021-01-25</encoding-date>
+   <encoder>STEPHEN SULLIVAN</encoder>
+   <software>Sibelius 20.12.0</software>
+   <software>Direct export, not from Dolet</software>
+   <encoding-description>Sibelius / MusicXML 3.0</encoding-description>
+   <supports element="print" type="yes" value="yes" attribute="new-system" />
+   <supports element="print" type="yes" value="yes" attribute="new-page" />
+   <supports element="accidental" type="yes" />
+   <supports element="beam" type="yes" />
+   <supports element="stem" type="yes" />
+  </encoding>
+ </identification>
+ <defaults>
+  <scaling>
+   <millimeters>215.9</millimeters>
+   <tenths>1233</tenths>
+  </scaling>
+  <page-layout>
+   <page-height>1595</page-height>
+   <page-width>1233</page-width>
+   <page-margins type="both">
+    <left-margin>85</left-margin>
+    <right-margin>85</right-margin>
+    <top-margin>85</top-margin>
+    <bottom-margin>85</bottom-margin>
+   </page-margins>
+  </page-layout>
+  <system-layout>
+   <system-margins>
+    <left-margin>71</left-margin>
+    <right-margin>0</right-margin>
+   </system-margins>
+   <system-distance>120</system-distance>
+  </system-layout>
+  <appearance>
+   <line-width type="stem">1.25</line-width>
+   <line-width type="beam">5</line-width>
+   <line-width type="staff">1.25</line-width>
+   <line-width type="light barline">1.5625</line-width>
+   <line-width type="heavy barline">5</line-width>
+   <line-width type="leger">1.5625</line-width>
+   <line-width type="ending">1.5625</line-width>
+   <line-width type="wedge">1.25</line-width>
+   <line-width type="enclosure">1.5625</line-width>
+   <line-width type="tuplet bracket">1.25</line-width>
+   <line-width type="bracket">5</line-width>
+   <line-width type="dashes">1.5625</line-width>
+   <line-width type="extend">0.9375</line-width>
+   <line-width type="octave shift">1.5625</line-width>
+   <line-width type="pedal">1.5625</line-width>
+   <line-width type="slur middle">1.5625</line-width>
+   <line-width type="slur tip">0.625</line-width>
+   <line-width type="tie middle">1.5625</line-width>
+   <line-width type="tie tip">0.625</line-width>
+   <note-size type="cue">75</note-size>
+   <note-size type="grace">60</note-size>
+  </appearance>
+  <music-font font-family="Opus Std" font-size="19.854" />
+  <word-font font-family="Plantin MT Std" font-size="11.9434" />
+  <lyric-font font-family="Plantin MT Std" font-size="11.4781" />
+  <lyric-language xml:lang="en" />
+ </defaults>
+ <credit page="1">
+  <credit-words default-x="616" default-y="165" font-family="Plantin MT Std" font-style="normal" font-size="22.0255" font-weight="normal" justify="center" valign="middle">Kpaste</credit-words>
+ </credit>
+ <credit page="1">
+  <credit-words default-x="616" default-y="160" font-family="Plantin MT Std" font-style="normal" font-size="10.0821" font-weight="normal" justify="center" valign="middle">Kpaste</credit-words>
+ </credit>
+ <part-list>
+  <score-part id="P1">
+   <part-name>Gankogui</part-name>
+   <part-name-display>
+    <display-text>Gankogui</display-text>
+   </part-name-display>
+   <part-abbreviation>Perc.</part-abbreviation>
+   <part-abbreviation-display>
+    <display-text>Perc.</display-text>
+   </part-abbreviation-display>
+   <score-instrument id="P1-I1">
+    <instrument-name>Percussion (2) (2) (2)</instrument-name>
+    <virtual-instrument>
+     <virtual-library>General MIDI</virtual-library>
+     <virtual-name>Standard Set</virtual-name>
+    </virtual-instrument>
+   </score-instrument>
+  </score-part>
+ </part-list>
+ <part id="P1">
+  <!--============== Part: P1, Measure: 1 ==============-->
+  <measure number="1" width="645">
+   <print new-page="yes">
+    <system-layout>
+     <system-margins>
+      <left-margin>126</left-margin>
+      <right-margin>0</right-margin>
+     </system-margins>
+     <top-system-distance>227</top-system-distance>
+    </system-layout>
+   </print>
+   <attributes>
+    <divisions>256</divisions>
+    <key color="#000000">
+     <fifths>0</fifths>
+     <mode>major</mode>
+    </key>
+    <time color="#000000">
+     <beats>4</beats>
+     <beat-type>4</beat-type>
+    </time>
+    <staves>1</staves>
+    <clef number="1" color="#000000">
+     <sign>percussion</sign>
+     <line>2</line>
+    </clef>
+    <staff-details number="1" print-object="yes">
+     <staff-lines>1</staff-lines>
+    </staff-details>
+   </attributes>
+   <note color="#000000" default-x="76" default-y="34">
+    <unpitched>
+     <display-step>C</display-step>
+     <display-octave>4</display-octave>
+    </unpitched>
+    <duration>192</duration>
+    <instrument id="P1-I1" />
+    <voice>1</voice>
+    <type>eighth</type>
+    <dot />
+    <stem>up</stem>
+    <staff>1</staff>
+    <beam number="1">begin</beam>
+   </note>
+   <note color="#000000" default-x="161" default-y="34">
+    <unpitched>
+     <display-step>D</display-step>
+     <display-octave>4</display-octave>
+    </unpitched>
+    <duration>64</duration>
+    <instrument id="P1-I1" />
+    <voice>1</voice>
+    <type>16th</type>
+    <stem>up</stem>
+    <staff>1</staff>
+    <beam number="1">end</beam>
+    <beam number="2">backward hook</beam>
+   </note>
+   <note default-x="216">
+    <unpitched>
+     <display-step>E</display-step>
+     <display-octave>4</display-octave>
+    </unpitched>
+    <duration>64</duration>
+    <instrument id="P1-I1" />
+    <voice>1</voice>
+    <type>16th</type>
+    <staff>1</staff>
+   </note>
+   <note color="#000000" default-x="271" default-y="37">
+    <unpitched>
+     <display-step>F</display-step>
+     <display-octave>4</display-octave>
+    </unpitched>
+    <duration>192</duration>
+    <instrument id="P1-I1" />
+    <voice>1</voice>
+    <type>eighth</type>
+    <dot />
+    <stem>up</stem>
+    <staff>1</staff>
+   </note>
+   <note color="#000000" default-x="357" default-y="34">
+    <unpitched>
+     <display-step>G</display-step>
+     <display-octave>4</display-octave>
+    </unpitched>
+    <duration>128</duration>
+    <instrument id="P1-I1" />
+    <voice>1</voice>
+    <type>eighth</type>
+    <stem>up</stem>
+    <staff>1</staff>
+    <beam number="1">begin</beam>
+   </note>
+   <note color="#000000" default-x="429" default-y="34">
+    <unpitched>
+     <display-step>A</display-step>
+     <display-octave>4</display-octave>
+    </unpitched>
+    <duration>128</duration>
+    <instrument id="P1-I1" />
+    <voice>1</voice>
+    <type>eighth</type>
+    <stem>up</stem>
+    <staff>1</staff>
+    <beam number="1">continue</beam>
+   </note>
+   <note color="#000000" default-x="501" default-y="34">
+    <unpitched>
+     <display-step>B</display-step>
+     <display-octave>4</display-octave>
+    </unpitched>
+    <duration>128</duration>
+    <instrument id="P1-I1" />
+    <voice>1</voice>
+    <type>eighth</type>
+    <stem>up</stem>
+    <staff>1</staff>
+    <beam number="1">continue</beam>
+   </note>
+   <note color="#000000" default-x="573" default-y="34">
+    <unpitched>
+     <display-step>C</display-step>
+     <display-octave>5</display-octave>
+    </unpitched>
+    <duration>128</duration>
+    <instrument id="P1-I1" />
+    <voice>1</voice>
+    <type>eighth</type>
+    <stem>up</stem>
+    <staff>1</staff>
+    <beam number="1">end</beam>
+   </note>
+  </measure>
+  <!--============== Part: P1, Measure: 2 ==============-->
+  <measure number="2" width="290">
+   <note>
+    <rest />
+    <duration>1024</duration>
+    <instrument id="P1-I1" />
+    <voice>1</voice>
+    <type>whole</type>
+    <staff>1</staff>
+   </note>
+   <barline>
+    <bar-style>light-heavy</bar-style>
+   </barline>
+  </measure>
+ </part>
+</score-partwise>