verovio icon indicating copy to clipboard operation
verovio copied to clipboard

Mixed beam layout refinement

Open craigsapp opened this issue 3 years ago • 1 comments

Here is a funny mixed-beam example:

Screen Shot 2021-01-14 at 9 15 06 AM

which should be renderd as:

Screen Shot 2021-01-14 at 9 04 24 AM

Part of the problem is related to issue https://github.com/rism-ch/verovio/issues/1032, but there is a separate issue which is specific to mixed beams: The spacing of mixed beams are controlled by stems rather than note heads. The goal for spacing would be to space the stems on the mixed beam evenly. In this case the middle note should have a stem touching the beam exactly at its middle (although other layout contexts could perturb that default spacing).

Click to view MEI data for example.
<?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-14T09:21:18" version="3.1.0-dev-0361cac-dirty">
     <name>Verovio</name>
     <p>Transcoded from Humdrum</p>
    </application>
   </appInfo>
  </encodingDesc>
  <workList>
   <work>
    <title />
   </work>
  </workList>
  </meiHead>
 <music>
  <body>
   <mdiv xml:id="mdiv-0000001676760591">
    <score xml:id="score-0000000715297447">
     <scoreDef xml:id="scoredef-0000000652114363" midi.bpm="120">
      <staffGrp xml:id="staffgrp-0000001472696674" bar.thru="true" symbol="brace">
       <staffDef xml:id="staffdef-0000000896913537" n="1" lines="5">
        <clef xml:id="clef-L2F2" shape="G" line="2" />
        <keySig xml:id="keysig-L3F2" pname="a" mode="major" sig="3s" />
        <meterSig xml:id="metersig-L5F2" count="2" unit="4" />
       </staffDef>
       <staffDef xml:id="staffdef-0000000219702801" n="2" lines="5">
        <clef xml:id="clef-L2F1" shape="F" line="4" />
        <keySig xml:id="keysig-L3F1" pname="a" mode="major" sig="3s" />
        <meterSig xml:id="metersig-L5F1" count="2" unit="4" />
       </staffDef>
      </staffGrp>
     </scoreDef>
     <section xml:id="section-L1F1">
      <measure xml:id="measure-L1" n="85">
       <staff xml:id="staff-0000000932469691" n="1">
        <layer xml:id="layer-L1F2N1" n="1">
         <tuplet xml:id="tuplet-L9F2-L11F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L9F2-L11F2" type="placed">
           <note xml:id="note-L9F2" dur="16" oct="4" pname="e" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L10F2" dur="16" oct="5" pname="e" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L11F2" dur="16" oct="4" pname="e" stem.dir="down" accid.ges="n" />
          </beam>
         </tuplet>
         <tuplet xml:id="tuplet-L12F2-L14F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L12F2-L14F2">
           <note xml:id="note-L12F2" type="placed" dur="16" staff="2" oct="3" pname="b" stem.dir="up" accid.ges="n" />
           <note xml:id="note-L13F2" type="placed" dur="16" oct="4" pname="b" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L14F2" type="placed" dur="16" staff="2" oct="3" pname="b" stem.dir="up" accid.ges="n" />
          </beam>
         </tuplet>
         <tuplet xml:id="tuplet-L15F2-L17F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L15F2-L17F2">
           <note xml:id="note-L15F2" type="placed" dur="16" staff="2" oct="3" pname="g" stem.dir="up" accid.ges="s" />
           <note xml:id="note-L16F2" type="placed" dur="16" oct="4" pname="g" stem.dir="down" accid.ges="s" />
           <note xml:id="note-L17F2" type="placed" dur="16" staff="2" oct="3" pname="g" stem.dir="up" accid.ges="s" />
          </beam>
         </tuplet>
         <tuplet xml:id="tuplet-L18F2-L20F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L18F2-L20F2">
           <note xml:id="note-L18F2" type="placed" dur="16" staff="2" oct="3" pname="e" stem.dir="up" accid.ges="n" />
           <note xml:id="note-L19F2" type="placed" dur="16" oct="4" pname="e" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L20F2" type="placed" dur="16" staff="2" oct="3" pname="e" stem.dir="up" accid.ges="n" />
          </beam>
         </tuplet>
        </layer>
       </staff>
       <staff xml:id="staff-0000001035786274" n="2">
        <layer xml:id="layer-L1F1N1" n="1">
         <mRest xml:id="mrest-L9F1" ploc="b" oloc="2" />
        </layer>
       </staff>
      </measure>
     </section>
    </score>
   </mdiv>
  </body>
 </music>
</mei>

In situ example: https://verovio.humdrum.org/?file=beethoven/sonatas/sonata02-1.krn&k=ey#mh85


Here is a reduced example with mixed beams and cross-staff permutations:

Screen Shot 2021-01-14 at 10 01 33 AM

In all cases the stems of the middle note should be exactly in the middle of the beam as illustrated for simple beaming in the third measure.

Mixed rhythms will need refinement from the basic equal-duration case, but probably should be spaced as if there were no mixed stemming as illustrated in measure 4. In other words, the spacing of the stems in measure 3 should match their positions in measure 4. The main different between spacing in measure 5 and measures 3 and 4 would be that accidentals in measure 5 would not change the stem spacings, while in measures 3 and 4 would have to shift the notes based on any accidentals that need to be allocated extra space.

The last two measure are examples of non-mixed non-cross-staff beams.

Click to view MEI data for above example.
<?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-14T10:01:35" version="3.1.0-dev-0361cac-dirty">
     <name>Verovio</name>
     <p>Transcoded from Humdrum</p>
    </application>
   </appInfo>
  </encodingDesc>
  <workList>
   <work>
    <title />
   </work>
  </workList>
 </meiHead>
 <music>
  <body>
   <mdiv xml:id="mdiv-0000000528122477">
    <score xml:id="score-0000000822911787">
     <scoreDef xml:id="scoredef-0000000652114363">
      <staffGrp xml:id="staffgrp-0000001641701229" bar.thru="true" symbol="brace">
       <staffDef xml:id="staffdef-0000001343957684" n="1" lines="5">
        <clef xml:id="clef-L2F2" shape="G" line="2" />
       </staffDef>
       <staffDef xml:id="staffdef-0000000309057130" n="2" lines="5">
        <clef xml:id="clef-L2F1" shape="F" line="4" />
       </staffDef>
      </staffGrp>
     </scoreDef>
     <section xml:id="section-L1F1">
      <measure xml:id="measure-L1">
       <staff xml:id="staff-0000001130430102" n="1">
        <layer xml:id="layer-L1F2N1" n="1">
         <tuplet xml:id="tuplet-L6F2-L8F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L6F2-L8F2">
           <note xml:id="note-L6F2" type="placed" dur="8" staff="2" oct="3" pname="e" stem.dir="up" accid.ges="n" />
           <note xml:id="note-L7F2" type="placed" dur="8" oct="4" pname="e" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L8F2" type="placed" dur="8" staff="2" oct="3" pname="e" stem.dir="up" accid.ges="n" />
          </beam>
         </tuplet>
         <tuplet xml:id="tuplet-L9F2-L11F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L9F2-L11F2">
           <note xml:id="note-L9F2" type="placed" dur="8" oct="4" pname="a" stem.dir="up" accid.ges="n" />
           <note xml:id="note-L10F2" type="placed" dur="8" staff="2" oct="3" pname="a" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L11F2" type="placed" dur="8" oct="4" pname="a" stem.dir="up" accid.ges="n" />
          </beam>
         </tuplet>
        </layer>
       </staff>
       <staff xml:id="staff-0000001025555020" n="2">
        <layer xml:id="layer-L1F1N1" n="1">
         <space xml:id="space-L6F1" dur="2" />
        </layer>
       </staff>
       <dir xml:id="dir-L5F1" place="above" staff="1" tstamp="1.000000">
        <rend xml:id="rend-0000000063340550" color="silver">cross-staff<lb xml:id="lb-0000000255200344" />and mixed beams</rend>
       </dir>
      </measure>
      <measure xml:id="measure-L12">
       <staff xml:id="staff-L12F2N1" n="1">
        <layer xml:id="layer-L12F2N1" n="1">
         <tuplet xml:id="tuplet-L14F2-L16F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L14F2-L16F2">
           <note xml:id="note-L14F2" type="placed" dur="8" oct="4" pname="c" stem.dir="up" accid.ges="n" />
           <note xml:id="note-L15F2" type="placed" dur="8" oct="5" pname="a" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L16F2" type="placed" dur="8" oct="4" pname="c" stem.dir="up" accid.ges="n" />
          </beam>
         </tuplet>
         <tuplet xml:id="tuplet-L17F2-L19F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L17F2-L19F2">
           <note xml:id="note-L17F2" type="placed" dur="8" oct="5" pname="a" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L18F2" type="placed" dur="8" oct="4" pname="c" stem.dir="up" accid.ges="n" />
           <note xml:id="note-L19F2" type="placed" dur="8" oct="5" pname="a" stem.dir="down" accid.ges="n" />
          </beam>
         </tuplet>
        </layer>
       </staff>
       <staff xml:id="staff-L12F1N1" n="2">
        <layer xml:id="layer-L12F1N1" n="1">
         <space xml:id="space-L14F1" dur="2" />
        </layer>
       </staff>
       <dir xml:id="dir-L13F2" place="below" staff="1" tstamp="1.000000">
        <rend xml:id="rend-0000001367473575" color="silver">mixed beams<lb xml:id="lb-0000000419898286" />on one staff</rend>
       </dir>
      </measure>
      <measure xml:id="measure-L20">
       <staff xml:id="staff-L20F2N1" n="1">
        <layer xml:id="layer-L20F2N1" n="1">
         <tuplet xml:id="tuplet-L21F2-L23F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L21F2-L23F2">
           <note xml:id="note-L21F2" dur="8" oct="4" pname="e" accid.ges="n" />
           <note xml:id="note-L22F2" dur="8" oct="4" pname="e" accid.ges="n" />
           <note xml:id="note-L23F2" dur="8" oct="4" pname="e" accid.ges="n" />
          </beam>
         </tuplet>
         <tuplet xml:id="tuplet-L24F2-L26F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L24F2-L26F2">
           <note xml:id="note-L24F2" dur="8" oct="5" pname="f" accid.ges="n" />
           <note xml:id="note-L25F2" dur="8" oct="5" pname="f" accid.ges="n" />
           <note xml:id="note-L26F2" dur="8" oct="5" pname="f" accid.ges="n" />
          </beam>
         </tuplet>
        </layer>
       </staff>
       <staff xml:id="staff-L20F1N1" n="2">
        <layer xml:id="layer-L20F1N1" n="1">
         <space xml:id="space-L21F1" dur="2" />
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L27">
       <staff xml:id="staff-L27F2N1" n="1">
        <layer xml:id="layer-L27F2N1" n="1">
         <tuplet xml:id="tuplet-L28F2-L31F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L28F2-L31F2">
           <note xml:id="note-L28F2" dur="16" oct="4" pname="e" accid.ges="n" />
           <note xml:id="note-L29F2" dur="8" oct="4" pname="e" accid.ges="n" />
           <note xml:id="note-L30F2" dur="8" oct="4" pname="e" accid.ges="n" />
           <note xml:id="note-L31F2" dur="16" oct="4" pname="e" accid.ges="n" />
          </beam>
         </tuplet>
         <tuplet xml:id="tuplet-L32F2-L35F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L32F2-L35F2">
           <note xml:id="note-L32F2" dur="8" oct="4" pname="e" accid.ges="n" />
           <note xml:id="note-L33F2" dur="16" oct="4" pname="e" accid.ges="n" />
           <note xml:id="note-L34F2" dur="16" oct="4" pname="e" accid.ges="n" />
           <note xml:id="note-L35F2" dur="8" oct="4" pname="e" accid.ges="n" />
          </beam>
         </tuplet>
        </layer>
       </staff>
       <staff xml:id="staff-L27F1N1" n="2">
        <layer xml:id="layer-L27F1N1" n="1">
         <space xml:id="space-L28F1" dur="2" />
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L36">
       <staff xml:id="staff-L36F2N1" n="1">
        <layer xml:id="layer-L36F2N1" n="1">
         <tuplet xml:id="tuplet-L37F2-L40F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L37F2-L40F2">
           <note xml:id="note-L37F2" type="placed" dur="16" oct="4" pname="c" stem.dir="up" accid.ges="n" />
           <note xml:id="note-L38F2" type="placed" dur="8" oct="5" pname="a" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L39F2" type="placed" dur="8" oct="5" pname="a" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L40F2" type="placed" dur="16" oct="4" pname="c" stem.dir="up" accid.ges="n" />
          </beam>
         </tuplet>
         <tuplet xml:id="tuplet-L41F2-L44F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count">
          <beam xml:id="beam-L41F2-L44F2">
           <note xml:id="note-L41F2" type="placed" dur="8" oct="4" pname="c" stem.dir="up" accid.ges="n" />
           <note xml:id="note-L42F2" type="placed" dur="16" oct="5" pname="a" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L43F2" type="placed" dur="16" oct="5" pname="a" stem.dir="down" accid.ges="n" />
           <note xml:id="note-L44F2" type="placed" dur="8" oct="4" pname="c" stem.dir="up" accid.ges="n" />
          </beam>
         </tuplet>
        </layer>
       </staff>
       <staff xml:id="staff-L36F1N1" n="2">
        <layer xml:id="layer-L36F1N1" n="1">
         <space xml:id="space-L37F1" dur="2" />
        </layer>
       </staff>
      </measure>
     </section>
    </score>
   </mdiv>
  </body>
 </music>
</mei>

craigsapp avatar Jan 14 '21 18:01 craigsapp

In SCORE there is a command called STUD (Stems Up/Down) for dealing with this situation. Here is a description for this starting on page 245 of the SCORE reference manual version 3.0:

Screen Shot 2021-01-20 at 9 08 30 AM Screen Shot 2021-01-20 at 9 08 49 AM

craigsapp avatar Jan 20 '21 17:01 craigsapp