rism-digital / verovio

🎵 Music notation engraving library for MEI with MusicXML and Humdrum support and various toolkits (JavaScript, Python)
https://www.verovio.org
GNU Lesser General Public License v3.0
678 stars 185 forks source link

Strange beam angle increase case #1943

Closed craigsapp closed 2 years ago

craigsapp commented 3 years ago

In the following music, the beams highlighted in purple are not typeset well. There is some extra lengthening of the stems which should not be done in these cases. The red note marks the side of the beam where the stem has been lengthened.

Screen Shot 2021-01-12 at 11 24 01 AM

Analog typesetting:

Screen Shot 2021-01-12 at 11 27 40 AM

MEI test data:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0">
 <meiHead>
  <fileDesc>
   <titleStmt>
    <title />
   </titleStmt>
   <pubStmt />
  </fileDesc>
  <encodingDesc>
   <appInfo>
    <application isodate="2021-01-12T11:22:09" version="3.1.0-dev-1666d80-dirty">
     <name>Verovio</name>
     <p>Transcoded from Humdrum</p>
    </application>
   </appInfo>
  </encodingDesc>
  <workList>
   <work>
    <title />
   </work>
  </workList>
  <extMeta>
   <frames xmlns="http://www.humdrum.org/ns/humxml">
    <metaFrame n="61" token="!!!RDF**kern: > = above" xml:id="L62">
     <frameInfo>
      <startTime float="6" />
      <frameType>reference</frameType>
      <referenceKey>RDF**kern</referenceKey>
      <referenceValue>&gt; = above</referenceValue>
     </frameInfo>
    </metaFrame>
    <metaFrame n="62" token="!!!RDF**kern: &lt; = below" xml:id="L63">
     <frameInfo>
      <startTime float="6" />
      <frameType>reference</frameType>
      <referenceKey>RDF**kern</referenceKey>
      <referenceValue>&lt; = below</referenceValue>
     </frameInfo>
    </metaFrame>
   </frames>
  </extMeta>
 </meiHead>
 <music>
  <body>
   <mdiv xml:id="mdiv-0000000321289766">
    <score xml:id="score-0000000465872206">
     <scoreDef xml:id="scoredef-0000001639171720" midi.bpm="60">
      <staffGrp xml:id="staffgrp-0000002079255644" bar.thru="true" symbol="brace">
       <staffDef xml:id="staffdef-0000001353456619" n="1" lines="5">
        <clef xml:id="clef-L2F2" shape="G" line="2" />
        <keySig xml:id="keysig-L3F2" pname="f" mode="major" sig="1f" />
        <meterSig xml:id="metersig-L5F2" count="3" unit="4" />
       </staffDef>
       <staffDef xml:id="staffdef-0000001116582746" n="2" lines="5">
        <clef xml:id="clef-L2F1" shape="F" line="4" />
        <keySig xml:id="keysig-L3F1" pname="f" mode="major" sig="1f" />
        <meterSig xml:id="metersig-L5F1" count="3" unit="4" />
       </staffDef>
      </staffGrp>
     </scoreDef>
     <section xml:id="section-L1F1">
      <pb xml:id="pb-0000001306036516" />
      <measure xml:id="measure-L1" n="26">
       <staff xml:id="staff-0000000284720019" n="1">
        <layer xml:id="layer-L1F2N1" n="1">
         <note xml:id="note-L8F2" dur="32" oct="5" pname="d" accid.ges="n" />
         <beam xml:id="beam-L9F2-L11F2">
          <note xml:id="note-L9F2" dur="32" oct="4" pname="d" accid.ges="n">
           <artic xml:id="artic-L9F2" artic="stacc" />
          </note>
          <note xml:id="note-L10F2" dur="32" oct="4" pname="e" accid.ges="n">
           <artic xml:id="artic-L10F2" artic="stacc" />
          </note>
          <note xml:id="note-L11F2" dur="32" oct="4" pname="f" accid.ges="n">
           <artic xml:id="artic-L11F2" artic="stacc" />
          </note>
         </beam>
         <beam xml:id="beam-L12F2-L15F2">
          <note xml:id="note-L12F2" dur="32" oct="4" pname="g" accid.ges="n">
           <artic xml:id="artic-L12F2" artic="stacc" />
          </note>
          <note xml:id="note-L13F2" dur="32" oct="4" pname="a" accid.ges="n">
           <artic xml:id="artic-L13F2" artic="stacc" />
          </note>
          <note xml:id="note-L14F2" dur="32" oct="4" pname="b" accid="n">
           <artic xml:id="artic-L14F2" artic="stacc" />
          </note>
          <note xml:id="note-L15F2" dur="32" oct="5" pname="c" accid="s">
           <artic xml:id="artic-L15F2" artic="stacc" />
          </note>
         </beam>
         <beam xml:id="beam-L16F2-L19F2">
          <note xml:id="note-L16F2" dur="32" oct="5" pname="d" accid.ges="n">
           <artic xml:id="artic-L16F2" artic="stacc" />
          </note>
          <note xml:id="note-L17F2" dur="32" oct="5" pname="d" accid.ges="n">
           <artic xml:id="artic-L17F2" artic="stacc" />
          </note>
          <note xml:id="note-L18F2" dur="32" oct="5" pname="e" accid.ges="n">
           <artic xml:id="artic-L18F2" artic="stacc" />
          </note>
          <note xml:id="note-L19F2" dur="32" oct="5" pname="f" accid.ges="n">
           <artic xml:id="artic-L19F2" artic="stacc" />
          </note>
         </beam>
         <beam xml:id="beam-L20F2-L23F2">
          <note xml:id="note-L20F2" dur="32" oct="5" pname="g" accid.ges="n">
           <artic xml:id="artic-L20F2" artic="stacc" />
          </note>
          <note xml:id="note-L21F2" dur="32" oct="5" pname="a" accid.ges="n">
           <artic xml:id="artic-L21F2" artic="stacc" />
          </note>
          <note xml:id="note-L22F2" dur="32" oct="5" pname="b" accid="n">
           <artic xml:id="artic-L22F2" artic="stacc" />
          </note>
          <note xml:id="note-L23F2" dur="32" oct="6" pname="c" accid="s">
           <artic xml:id="artic-L23F2" artic="stacc" />
          </note>
         </beam>
         <beam xml:id="beam-L24F2-L27F2" color="purple">
          <note xml:id="note-L24F2" dur="32" oct="6" color="red" pname="d" accid.ges="n">
           <artic xml:id="artic-L24F2" artic="stacc" />
          </note>
          <note xml:id="note-L25F2" dur="32" oct="6" pname="e" accid.ges="n">
           <artic xml:id="artic-L25F2" artic="stacc" />
          </note>
          <note xml:id="note-L26F2" dur="32" oct="6" pname="f" accid.ges="n">
           <artic xml:id="artic-L26F2" artic="stacc" />
          </note>
          <note xml:id="note-L27F2" dur="32" oct="6" pname="e" accid.ges="n">
           <artic xml:id="artic-L27F2" artic="stacc" />
          </note>
         </beam>
         <beam xml:id="beam-L28F2-L31F2">
          <note xml:id="note-L28F2" dur="32" oct="6" pname="d" accid.ges="n">
           <artic xml:id="artic-L28F2" artic="stacc" />
          </note>
          <note xml:id="note-L29F2" dur="32" oct="6" pname="c" accid="n">
           <artic xml:id="artic-L29F2" artic="stacc" />
          </note>
          <note xml:id="note-L30F2" dur="32" oct="5" pname="b" accid.ges="n">
           <artic xml:id="artic-L30F2" artic="stacc" />
          </note>
          <note xml:id="note-L31F2" dur="32" oct="5" pname="a" accid.ges="n">
           <artic xml:id="artic-L31F2" artic="stacc" />
          </note>
         </beam>
        </layer>
       </staff>
       <staff xml:id="staff-0000002020650651" n="2">
        <layer xml:id="layer-L1F1N1" n="1">
         <note xml:id="note-L8F1" dur="8" oct="3" pname="f" accid.ges="n" />
         <rest xml:id="rest-L12F1" dur="8" />
         <chord xml:id="chord-L16F1" dur="8">
          <note xml:id="note-L16F1S1" oct="3" pname="f" accid.ges="n" />
          <note xml:id="note-L16F1S2" oct="3" pname="a" accid.ges="n" />
         </chord>
         <rest xml:id="rest-L20F1" dur="8" />
         <chord xml:id="chord-L24F1" dur="8">
          <note xml:id="note-L24F1S1" oct="3" pname="f" accid.ges="n" />
          <note xml:id="note-L24F1S2" oct="3" pname="a" accid.ges="n" />
         </chord>
         <rest xml:id="rest-L28F1" dur="8" />
        </layer>
       </staff>
       <dynam xml:id="dynam-L8F3" staff="1" tstamp="1.000000" vgrp="100">p</dynam>
      </measure>
      <measure xml:id="measure-L32" n="27">
       <staff xml:id="staff-L32F2N1" n="1">
        <layer xml:id="layer-L32F2N1" n="1">
         <chord xml:id="chord-L34F2" dots="1" dur="2">
          <note xml:id="note-L34F2S1" oct="5" pname="e" accid.ges="n" />
          <note xml:id="note-L34F2S2" oct="5" pname="g" accid.ges="n" />
         </chord>
        </layer>
        <layer xml:id="layer-L34F3N2" n="2">
         <chord xml:id="chord-L34F3" dur="4">
          <note xml:id="note-L34F3S1" oct="4" pname="g" accid.ges="n" />
          <note xml:id="note-L34F3S2" oct="5" pname="c" accid.ges="n" />
         </chord>
         <rest xml:id="rest-L42F3" dur="4" />
         <rest xml:id="rest-L50F3" dur="4" />
        </layer>
       </staff>
       <staff xml:id="staff-L32F1N1" n="2">
        <layer xml:id="layer-L32F1N1" n="1">
         <rest xml:id="rest-L34F1" dur="32" />
         <beam xml:id="beam-L35F1-L37F1" color="purple">
          <note xml:id="note-L35F1" dur="32" oct="1" pname="g" accid.ges="n" />
          <note xml:id="note-L36F1" dur="32" oct="1" pname="a" accid.ges="n" />
          <note xml:id="note-L37F1" dur="32" oct="1" color="red" pname="b" accid="n" />
         </beam>
         <beam xml:id="beam-L38F1-L41F1">
          <note xml:id="note-L38F1" dur="32" oct="2" pname="c" accid.ges="n" />
          <note xml:id="note-L39F1" dur="32" oct="2" pname="d" accid.ges="n" />
          <note xml:id="note-L40F1" dur="32" oct="2" pname="e" accid.ges="n" />
          <note xml:id="note-L41F1" dur="32" oct="2" pname="f" accid.ges="n" />
         </beam>
         <beam xml:id="beam-L42F1-L45F1">
          <note xml:id="note-L42F1" dur="32" oct="2" pname="g" accid.ges="n" />
          <note xml:id="note-L43F1" dur="32" oct="2" pname="g" accid.ges="n" />
          <note xml:id="note-L44F1" dur="32" oct="2" pname="a" accid.ges="n" />
          <note xml:id="note-L45F1" dur="32" oct="2" pname="b" accid="n" />
         </beam>
         <beam xml:id="beam-L46F1-L49F1">
          <note xml:id="note-L46F1" dur="32" oct="3" pname="c" accid.ges="n" />
          <note xml:id="note-L47F1" dur="32" oct="3" pname="d" accid.ges="n" />
          <note xml:id="note-L48F1" dur="32" oct="3" pname="e" accid.ges="n" />
          <note xml:id="note-L49F1" dur="32" oct="3" pname="f" accid.ges="n" />
         </beam>
         <beam xml:id="beam-L50F1-L53F1">
          <note xml:id="note-L50F1" dur="32" oct="3" pname="g" accid.ges="n" />
          <note xml:id="note-L51F1" dur="32" oct="3" pname="g" accid.ges="n" />
          <note xml:id="note-L52F1" dur="32" oct="3" pname="a" accid.ges="n" />
          <note xml:id="note-L53F1" dur="32" oct="3" pname="b" accid="n" />
         </beam>
         <beam xml:id="beam-L54F1-L57F1">
          <note xml:id="note-L54F1" dur="32" oct="4" pname="c" accid.ges="n" />
          <note xml:id="note-L55F1" dur="32" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L56F1" dur="32" oct="4" pname="e" accid.ges="n" />
          <note xml:id="note-L57F1" dur="32" oct="4" pname="f" accid.ges="n" />
         </beam>
        </layer>
       </staff>
       <dynam xml:id="dynam-L34F4" staff="1" tstamp="1.000000" vgrp="100">f</dynam>
       <slur xml:id="slur-L35F1-L42F1" staff="2" startid="#note-L35F1" endid="#note-L42F1" />
       <slur xml:id="slur-L43F1-L50F1" staff="2" startid="#note-L43F1" endid="#note-L50F1" />
       <tie xml:id="tie-L34F2S1-L59F2" type="hanging-terminal" staff="1" startid="#note-L34F2S1" tstamp2="0m+4.0000" />
       <tie xml:id="tie-L34F2S2-L59F2" type="hanging-terminal" staff="1" startid="#note-L34F2S2" tstamp2="0m+4.0000" />
      </measure>
      <sb xml:id="sb-L59F1" type="z" />
     </section>
    </score>
   </mdiv>
  </body>
 </music>
</mei>

In situ example:

https://verovio.humdrum.org/?file=mozart/sonatas/sonata08-2.krn#mh26

craigsapp commented 3 years ago

Here is a related case (may or may not be the same):

In this example, there is one beam that stands out as odd:

Screen Shot 2021-01-18 at 6 47 46 AM

Other than that it has red notes attached to it, the beam is much flatter than the other beams that contain similar intervallic content. This sudden change in beam angle for similar intervallic content decreases the readability of the music.

```xml </titleStmt> <pubStmt /> </fileDesc> <encodingDesc> <appInfo> <application isodate="2021-01-18T06:45:26" version="3.2.0-dev-219f1ca-dirty"> <name>Verovio</name> <p>Transcoded from Humdrum</p> </application> </appInfo> </encodingDesc> <workList> <work> <title xml:id="title-L1" analog="humdrum:Xfi" type="translated">extract -s 1,3
```

Here is a test looking at the beam angles in more detail:

Screen Shot 2021-01-18 at 6 44 33 AM

Starting at the B4-B3 note group, the beam suddenly gets flatter for no apparent reason. There is extra stem length added to the B3 that may be a bug; otherwise, I do not understand why it would be a valid typography style. It would be preferable to keen an angle in the beam in as in the earlier examples to make the top of the staff more visible.

Monceber commented 2 years ago

Seems like its fixed as well. image

Although, I'm not sure if in this case beams being horizontal is satisfactory. image

craigsapp commented 2 years ago

Yes, the horizontal beams are not pretty, but they are valid in the sense that the notes are all far from the staff and it is expected that the stem endpoints all end at the same line (typically the middle line, but for these 32nd notes, it is better to be one line above/below to avoid the beam being on the top/bottom lines for pitch readability purposes).

Here is the next most valid positions for the purple beams (when following the rule that beam end points must be attached to a staff line):

Screen Shot 2022-06-09 at 10 34 30 AM

The second one does not look bad, but the first one looks a little strange in isolation (moving up a third, but there is a downward motion at the end which is contradicting the steep slope).

The beam following the first purple beam is violating that rule, but look OK to me:

Screen Shot 2022-06-09 at 10 38 21 AM