Sfoglia il codice sorgente

merge osmd-public develop (1.5.5) - fix slash noteheads, first measure number with RenderMeasureNumbersOnlyAtSystemStart

sschmidTU 2 anni fa
parent
commit
4dcfe25ba1

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "osmd-extended",
-  "version": "1.5.4",
+  "version": "1.5.5",
   "description": "Private / sponsor exclusive OSMD mirror/audio player.",
   "main": "build/opensheetmusicdisplay.min.js",
   "types": "build/dist/src/index.d.ts",

+ 6 - 2
src/MusicalScore/Graphical/MusicSheetCalculator.ts

@@ -427,10 +427,14 @@ export abstract class MusicSheetCalculator {
         let previousMeasureNumber: number = staffLine.Measures[0].MeasureNumber;
         let labelOffsetX: number = 0;
         for (let i: number = 0; i < staffLine.Measures.length; i++) {
-            if (this.rules.RenderMeasureNumbersOnlyAtSystemStart && i > 0) {
+            const measure: GraphicalMeasure = staffLine.Measures[i];
+            let skip: boolean = this.rules.RenderMeasureNumbersOnlyAtSystemStart && i > 1;
+            if (i === 1 && staffLine.Measures[0].parentSourceMeasure.ImplicitMeasure) {
+                skip = false; // if the first measure (i=0) is a pickup measure, we shouldn't skip measure number 1 (i=1)
+            }
+            if (skip) {
                 return; // no more measures number labels need to be rendered for this system, so we can just return instead of continue.
             }
-            const measure: GraphicalMeasure = staffLine.Measures[i];
             if (measure.MeasureNumber === 0 || measure.MeasureNumber === 1) {
                 previousMeasureNumber = measure.MeasureNumber;
                 // for the first measure, this label still needs to be created. Afterwards, this variable will hold the previous label's measure number.

+ 14 - 10
src/MusicalScore/Graphical/VexFlow/VexFlowConverter.ts

@@ -268,7 +268,6 @@ export class VexFlowConverter {
         let numDots: number = baseNote.numberOfDots;
         let alignCenter: boolean = false;
         let xShift: number = 0;
-        let slashNoteHead: boolean = false;
         let isRest: boolean = false;
         let restYPitch: Pitch;
         for (const note of notes) {
@@ -416,14 +415,6 @@ export class VexFlowConverter {
                 break;
             }
 
-            if (note.sourceNote.Notehead) {
-                if (note.sourceNote.Notehead.Shape === NoteHeadShape.SLASH) {
-                    slashNoteHead = true;
-                    // if we have slash heads and other heads in the voice entry, this will create the same head for all.
-                    // same problem with numDots. The slash case should be extremely rare though.
-                }
-            }
-
             const pitch: [string, string, ClefInstruction] = (note as VexFlowGraphicalNote).vfpitch;
             keys.push(pitch[0]);
             accidentals.push(pitch[1]);
@@ -436,7 +427,9 @@ export class VexFlowConverter {
         for (let i: number = 0, len: number = numDots; i < len; ++i) {
             duration += "d";
         }
-        if (slashNoteHead) {
+        if (notes.length === 1 && notes[0].sourceNote.Notehead?.Shape === NoteHeadShape.SLASH) {
+            //if there are multiple note heads, all of them will be slash note head if done like this
+            //  -> see note_type = "s" below
             duration += "s"; // we have to specify a slash note head like this in Vexflow
         }
         if (isRest) {
@@ -471,6 +464,17 @@ export class VexFlowConverter {
         if (lineShift !== 0) {
             vfnote.getKeyProps()[0].line += lineShift;
         }
+        // check for slash noteheads (among other noteheads)
+        if (notes.length > 1) {
+            // for a single note, we can use duration += "s" (see above).
+            //   If we use the below solution for a single note as well, the notehead sometimes goes over the stem.
+            for (let n: number = 0; n < notes.length; n++) {
+                const note: VexFlowGraphicalNote = notes[n] as VexFlowGraphicalNote;
+                if (note.sourceNote.Notehead?.Shape === NoteHeadShape.SLASH) {
+                    (vfnote as any).note_heads[n].note_type = "s"; // slash notehead
+                }
+            }
+        }
 
         // Annotate GraphicalNote with which line of the staff it appears on
         vfnote.getKeyProps().forEach(({ line }, i) => gve.notes[i].staffLine = line);

+ 1 - 1
src/OpenSheetMusicDisplay/OpenSheetMusicDisplay.ts

@@ -35,7 +35,7 @@ import { DynamicsCalculator } from "../MusicalScore/ScoreIO/MusicSymbolModules/D
  * After the constructor, use load() and render() to load and render a MusicXML file.
  */
 export class OpenSheetMusicDisplay {
-    private version: string = "1.5.4-audio-extended"; // getter: this.Version
+    private version: string = "1.5.5-audio-extended"; // getter: this.Version
     // at release, bump version and change to -release, afterwards to -dev again
 
     /**

+ 1 - 0
src/VexFlowPatch/readme.txt

@@ -46,6 +46,7 @@ Fix stem/flag formatting. Instead of shifting notes by default, update the stem/
   Only offset if a note is the same voice, same note.
   (not yet in vexflow 4, PR 1263 open)
 able to add svg node id+class to stem (merged vexflow 4.x)
+Save and restore noteheads (e.g. slash noteheads) in reset()
 
 staverepetition.js (fixed vexflow 4):
 add TO_CODA enum to type() and draw()

+ 9 - 1
src/VexFlowPatch/src/stavenote.js

@@ -428,8 +428,16 @@ export class StaveNote extends StemmableNote {
 
     // Save prior noteHead styles & reapply them after making new noteheads.
     const noteHeadStyles = this.note_heads.map(noteHead => noteHead.getStyle());
+    // VexFlowPatch: save and restore noteheads (e.g. slash noteheads)
+    const note_types = [];
+    this.note_heads.forEach(head => note_types.push(head.note_type));
     this.buildNoteHeads();
-    this.note_heads.forEach((noteHead, index) => noteHead.setStyle(noteHeadStyles[index]));
+    this.note_heads.forEach((noteHead, index) => {
+      noteHead.setStyle(noteHeadStyles[index]);
+      if (note_types[index]) {
+        noteHead.note_type = note_types[index];
+      }
+    });
 
     if (this.stave) {
       this.note_heads.forEach(head => head.setStave(this.stave));

+ 354 - 0
test/data/test_drums_slash_chord.musicxml

@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise version="3.1">
+  <work>
+    <work-title>test_drums_slash_chord</work-title>
+    </work>
+  <identification>
+    <encoding>
+      <software>MuseScore 3.6.2</software>
+      <encoding-date>2022-09-14</encoding-date>
+      <supports element="accidental" type="yes"/>
+      <supports element="beam" type="yes"/>
+      <supports element="print" attribute="new-page" type="yes" value="yes"/>
+      <supports element="print" attribute="new-system" type="yes" value="yes"/>
+      <supports element="stem" type="yes"/>
+      </encoding>
+    </identification>
+  <defaults>
+    <scaling>
+      <millimeters>6.99911</millimeters>
+      <tenths>40</tenths>
+      </scaling>
+    <page-layout>
+      <page-height>1697.36</page-height>
+      <page-width>1200.15</page-width>
+      <page-margins type="even">
+        <left-margin>85.7252</left-margin>
+        <right-margin>85.7252</right-margin>
+        <top-margin>85.7252</top-margin>
+        <bottom-margin>85.7252</bottom-margin>
+        </page-margins>
+      <page-margins type="odd">
+        <left-margin>85.7252</left-margin>
+        <right-margin>85.7252</right-margin>
+        <top-margin>85.7252</top-margin>
+        <bottom-margin>85.7252</bottom-margin>
+        </page-margins>
+      </page-layout>
+    <word-font font-family="Edwin" font-size="10"/>
+    <lyric-font font-family="Edwin" font-size="10"/>
+    </defaults>
+  <credit page="1">
+    <credit-type>title</credit-type>
+    <credit-words default-x="600.076" default-y="1611.63" justify="center" valign="top" font-size="22">Bossa Nova 2:3</credit-words>
+    </credit>
+  <part-list>
+    <score-part id="P1">
+      <part-name>Bossa Nova 2:3</part-name>
+      <part-abbreviation>Bossa Nova 2:3</part-abbreviation>
+      <score-instrument id="P1-I37">
+        <instrument-name>BD</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I38">
+        <instrument-name>Side Stick</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I39">
+        <instrument-name>???????????? ????? ???????</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I41">
+        <instrument-name>????????????? ????? ???????</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I42">
+        <instrument-name>?????? ????????? ???</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I43">
+        <instrument-name>???????? ???</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I44">
+        <instrument-name>??????? ????????? ???</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I45">
+        <instrument-name>????????? ???-????</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I46">
+        <instrument-name>Low Tom</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I47">
+        <instrument-name>???????? ???</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I48">
+        <instrument-name>Low-Mid Tom</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I49">
+        <instrument-name>Hi-Mid Tom</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I50">
+        <instrument-name>Crash Cymbal 1</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I51">
+        <instrument-name>High Tom</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I52">
+        <instrument-name>???????-???? 1</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I53">
+        <instrument-name>Chinese Cymbal</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I54">
+        <instrument-name>Ride Bell</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I55">
+        <instrument-name>?????</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I56">
+        <instrument-name>?????</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I57">
+        <instrument-name>Cowbell</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I58">
+        <instrument-name>Crash Cymbal 2</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I60">
+        <instrument-name>???????-???? 2</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I64">
+        <instrument-name>???????? ??????? ?????</instrument-name>
+        </score-instrument>
+      <score-instrument id="P1-I65">
+        <instrument-name>Low Conga</instrument-name>
+        </score-instrument>
+      <midi-device port="1"></midi-device>
+      <midi-instrument id="P1-I37">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>37</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I38">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>38</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I39">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>39</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I41">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>41</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I42">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>42</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I43">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>43</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I44">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>44</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I45">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>45</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I46">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>46</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I47">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>47</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I48">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>48</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I49">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>49</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I50">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>50</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I51">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>51</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I52">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>52</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I53">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>53</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I54">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>54</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I55">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>55</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I56">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>56</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I57">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>57</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I58">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>58</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I60">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>60</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I64">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>64</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      <midi-instrument id="P1-I65">
+        <midi-channel>10</midi-channel>
+        <midi-program>1</midi-program>
+        <midi-unpitched>65</midi-unpitched>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      </score-part>
+    </part-list>
+  <part id="P1">
+    <measure number="1" width="307.52">
+      <print>
+        <system-layout>
+          <system-margins>
+            <left-margin>50.00</left-margin>
+            <right-margin>671.18</right-margin>
+            </system-margins>
+          <top-system-distance>170.00</top-system-distance>
+          </system-layout>
+        </print>
+      <attributes>
+        <divisions>1</divisions>
+        <key>
+          <fifths>0</fifths>
+          </key>
+        <time>
+          <beats>2</beats>
+          <beat-type>4</beat-type>
+          </time>
+        <clef>
+          <sign>percussion</sign>
+          <line>2</line>
+          </clef>
+        </attributes>
+      <note default-x="62.21" default-y="-15.00">
+        <unpitched>
+          <display-step>C</display-step>
+          <display-octave>5</display-octave>
+          </unpitched>
+        <duration>1</duration>
+        <instrument id="P1-I38"/>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>down</stem>
+        <notehead>slash</notehead>
+        </note>
+      <note default-x="62.21" default-y="5.00">
+        <chord/>
+        <unpitched>
+          <display-step>G</display-step>
+          <display-octave>5</display-octave>
+          </unpitched>
+        <duration>1</duration>
+        <instrument id="P1-I43"/>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>down</stem>
+        <notehead>x</notehead>
+        </note>
+      <note>
+        <rest/>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        </note>
+      <barline location="right">
+        <bar-style>light-heavy</bar-style>
+        </barline>
+      </measure>
+    </part>
+  </score-partwise>