Skip to content

Take into account key changes not only from the first staff #3877

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Daniel63656 opened this issue Dec 5, 2024 · 11 comments
Open

Take into account key changes not only from the first staff #3877

Daniel63656 opened this issue Dec 5, 2024 · 11 comments

Comments

@Daniel63656
Copy link

Verovio renders wrong key signatures for the minimal musicxml example I attached.

It should look like this (rendered using musescore):
musescore
but verovio renders key signatures wrong for second part:
verovio

Here the musicxml to reproduce the behaviour:

<?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">
  <movement-title>Pop Medley</movement-title>
  <identification>
    <creator type="arranger">Arr. by </creator>
    <creator type="composer">Various Artists</creator>
    <creator type="lyricist">Various Lyricists</creator>
    <rights>Copyright © To Their Respective Owners / MuseScore
Arreglo / Score</rights>
    <encoding>
      <software>MuseScore 3.6.2</software>
      <encoding-date>2024-12-05</encoding-date>
      <supports element="accidental" type="yes"/>
      <supports element="beam" type="yes"/>
      <supports element="print" attribute="new-page" type="no"/>
      <supports element="print" attribute="new-system" type="no"/>
      <supports element="stem" type="yes"/>
      </encoding>
    <source>http://musescore.com/score/2454866</source>
    </identification>
  <defaults>
    <scaling>
      <millimeters>7.23192</millimeters>
      <tenths>40</tenths>
      </scaling>
    <page-layout>
      <page-height>1545</page-height>
      <page-width>1193.99</page-width>
      <page-margins type="both">
        <left-margin>139.999</left-margin>
        <right-margin>139.999</right-margin>
        <top-margin>69.9998</top-margin>
        <bottom-margin>69.9998</bottom-margin>
        </page-margins>
      </page-layout>
    <word-font font-family="Helvetica Neue" font-size="10.25"/>
    <lyric-font font-family="FreeSerif" font-size="11"/>
    </defaults>
  <credit page="1">
    <credit-type>rights</credit-type>
    <credit-words default-x="596.995" default-y="69.9998" justify="center" valign="bottom">Copyright © To Their Respective Owners / MuseScore
Arreglo / Score</credit-words>
    </credit>
  <part-list>
    <score-part id="P1">
      <part-name>Trompette en Si♭</part-name>
      <part-abbreviation>Tromp. Si♭</part-abbreviation>
      <score-instrument id="P1-I1">
        <instrument-name>Trompette en Si♭</instrument-name>
        </score-instrument>
      <midi-device id="P1-I1" port="1"></midi-device>
      <midi-instrument id="P1-I1">
        <midi-channel>1</midi-channel>
        <midi-program>57</midi-program>
        <volume>78.7402</volume>
        <pan>0</pan>
        </midi-instrument>
      </score-part>
    <score-part id="P2">
      <part-name>Piano</part-name>
      <part-abbreviation>Pno.</part-abbreviation>
      <score-instrument id="P2-I1">
        <instrument-name>SmartMusic SoftSynth</instrument-name>
        </score-instrument>
      <midi-device id="P2-I1" port="1"></midi-device>
      <midi-instrument id="P2-I1">
        <midi-channel>3</midi-channel>
        <midi-program>1</midi-program>
        <volume>79.5276</volume>
        <pan>-34</pan>
        </midi-instrument>
      </score-part>
    </part-list>
  <part id="P1">
    <measure number="1" width="246.16">
      <print>
        <system-layout>
          <system-margins>
            <left-margin>187.22</left-margin>
            <right-margin>0.00</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>4</beats>
          <beat-type>4</beat-type>
          </time>
        <clef>
          <sign>G</sign>
          <line>2</line>
          </clef>
        <transpose>
          <diatonic>-1</diatonic>
          <chromatic>-2</chromatic>
          </transpose>
        </attributes>
      <note>
        <rest/>
        <duration>4</duration>
        <voice>1</voice>
        <type>whole</type>
        </note>
      </measure>
    <measure number="2" width="209.32">
      <attributes>
        <key>
          <fifths>6</fifths>
          </key>
        </attributes>
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>1</voice>
        </note>
      </measure>
    <measure number="3" width="154.76">
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>1</voice>
        </note>
      <barline location="right">
        <bar-style>light-light</bar-style>
        </barline>
      </measure>
    <measure number="4" width="186.53">
      <attributes>
        <key>
          <fifths>-1</fifths>
          </key>
        </attributes>
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>1</voice>
        </note>
      <barline location="right">
        <bar-style>light-heavy</bar-style>
        </barline>
      </measure>
    </part>
  <part id="P2">
    <measure number="1" width="246.16">
      <print>
        <staff-layout number="1">
          <staff-distance>65.00</staff-distance>
          </staff-layout>
        <staff-layout number="2">
          <staff-distance>65.00</staff-distance>
          </staff-layout>
        </print>
      <attributes>
        <divisions>1</divisions>
        <key>
          <fifths>-2</fifths>
          <mode>major</mode>
          </key>
        <time>
          <beats>4</beats>
          <beat-type>4</beat-type>
          </time>
        <staves>2</staves>
        <clef number="1">
          <sign>G</sign>
          <line>2</line>
          </clef>
        <clef number="2">
          <sign>F</sign>
          <line>4</line>
          </clef>
        </attributes>
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>1</voice>
        <staff>1</staff>
        </note>
      <backup>
        <duration>4</duration>
        </backup>
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>5</voice>
        <staff>2</staff>
        </note>
      </measure>
    <measure number="2" width="209.32">
      <attributes>
        <key>
          <fifths>4</fifths>
          <mode>major</mode>
          </key>
        </attributes>
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>1</voice>
        <staff>1</staff>
        </note>
      <backup>
        <duration>4</duration>
        </backup>
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>5</voice>
        <staff>2</staff>
        </note>
      </measure>
    <measure number="3" width="154.76">
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>1</voice>
        <staff>1</staff>
        </note>
      <backup>
        <duration>4</duration>
        </backup>
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>5</voice>
        <staff>2</staff>
        </note>
      <barline location="right">
        <bar-style>light-light</bar-style>
        </barline>
      </measure>
    <measure number="4" width="186.53">
      <attributes>
        <key>
          <fifths>-3</fifths>
          <mode>major</mode>
          </key>
        </attributes>
      <note>
        <rest/>
        <duration>4</duration>
        <voice>1</voice>
        <type>whole</type>
        <staff>1</staff>
        </note>
      <backup>
        <duration>4</duration>
        </backup>
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>5</voice>
        <staff>2</staff>
        </note>
      <barline location="right">
        <bar-style>light-heavy</bar-style>
        </barline>
      </measure>
    </part>
  </score-partwise>
@lpugin
Copy link
Contributor

lpugin commented Dec 5, 2024

The file does not import into Finale and Dorico. Is does import into MuseScore 4 (4.4.3). Exporting MusicXML from it or MEI both work properly with Verovio, so this it more looking like a bad data issue than a Verovio one.

@rettinghaus
Copy link
Contributor

Verovios MusicXML importer only takes key changes from the first staff into account.

@Daniel63656
Copy link
Author

First staff in part or in general?
Plans on fixing this?

@rettinghaus
Copy link
Contributor

In general. No plans right now to fix this. For now you should go with the proposed workarounds.

@Daniel63656
Copy link
Author

Ok. The same holds true for time signatures I guess?
But not clefs?

@rettinghaus
Copy link
Contributor

Clefs should work fine.

@rigaux
Copy link

rigaux commented May 17, 2025

Hello there.

We are facing the same issue with an OMR system we are working on. The signature for transposed instruments is aligned with the other ones, even though they are correct in the MusicXML source.

I understand that there is no short term plan to fix that, but you mention a "workaround" above. I could not find any specific info about such a workaround. Any clue ?

Again and again, thanks for this wonderful tool.

PR

@craigsapp
Copy link
Contributor

I don't have a problem converting from MusicXML to Humdrum to MEI:

Image

[View in VHV]

Click here for final MEI conversion (alt-m in VHV)
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/5.1/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/5.1/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.1">
 <meiHead>
  <fileDesc>
   <titleStmt>
    <title>Pop Medley</title>
   </titleStmt>
   <pubStmt>
    <unpub>This MEI file was created by Verovio's Humdrum converter. When published, this unpub element should be removed, and the enclosing pubStmt element should be properly filled out.</unpub>
   </pubStmt>
   <sourceDesc>
    <source type="digital">
     <bibl>
      <title>Pop Medley</title>
      <composer>
       <persName>Various Artists</persName>
      </composer>
      <availability>
       <useRestrict type="copyrightStatement" analog="humdrum:YEM">Copyright © To Their Respective Owners / MuseScore Arreglo / Score</useRestrict>
      </availability>
     </bibl>
    </source>
   </sourceDesc>
  </fileDesc>
  <encodingDesc>
   <appInfo>
    <application isodate="2025-05-17T09:47:12" version="5.2.0-dev-4660ee3-dirty">
     <name>Verovio</name>
     <p>Transcoded from Humdrum</p>
    </application>
   </appInfo>
  </encodingDesc>
  <workList>
   <work xml:id="work0_encoded" type="encoded">
    <title type="uniform">
     <titlePart type="main" analog="humdrum:OTL">Pop Medley</titlePart>
    </title>
    <composer>
     <persName analog="humdrum:COM">Various Artists</persName>
    </composer>
   </work>
  </workList>
  <extMeta>
   <frames xmlns="http://www.humdrum.org/ns/humxml">
    <metaFrame n="0" token="!!!COM: Various Artists" xml:id="L1">
     <frameInfo>
      <startTime float="0" />
      <frameType>reference</frameType>
      <referenceKey>COM</referenceKey>
      <referenceValue>Various Artists</referenceValue>
     </frameInfo>
    </metaFrame>
    <metaFrame n="1" token="!!!OTL: Pop Medley" xml:id="L2">
     <frameInfo>
      <startTime float="0" />
      <frameType>reference</frameType>
      <referenceKey>OTL</referenceKey>
      <referenceValue>Pop Medley</referenceValue>
     </frameInfo>
    </metaFrame>
    <metaFrame n="26" token="!!!system-decoration: s1{(s2,s3)}" xml:id="L27">
     <frameInfo>
      <startTime float="16" />
      <frameType>reference</frameType>
      <referenceKey>system-decoration</referenceKey>
      <referenceValue>s1{(s2,s3)}</referenceValue>
     </frameInfo>
    </metaFrame>
    <metaFrame n="27" token="!!!YEM: Copyright © To Their Respective Owners / MuseScore Arreglo / Score" xml:id="L28">
     <frameInfo>
      <startTime float="16" />
      <frameType>reference</frameType>
      <referenceKey>YEM</referenceKey>
      <referenceValue>Copyright © To Their Respective Owners / MuseScore Arreglo / Score</referenceValue>
     </frameInfo>
    </metaFrame>
   </frames>
  </extMeta>
 </meiHead>
 <music decls="#work0_encoded">
  <body>
   <mdiv xml:id="x18zgujv">
    <score xml:id="zztklxz">
     <scoreDef xml:id="amlcj92" midi.bpm="400" tempo.dist="3vu">
      <pgHead xml:id="o1n2z872" func="first">
       <rend xml:id="dik47dn" halign="center" valign="middle">
        <rend xml:id="s6uvkf0" fontsize="large">Pop Medley</rend>
        <lb xml:id="p19c1epi" /> 
<lb xml:id="q1nke94y" /> </rend>
       <rend xml:id="zlzxv4h" halign="right" valign="bottom" fontsize="small">Various Artists</rend>
      </pgHead>
      <staffGrp xml:id="n1sxr6qm" bar.thru="false">
       <staffGrp xml:id="hb8soca" bar.thru="false">
        <staffDef xml:id="staffdef-L3F3" n="1" lines="5" trans.diat="-1" trans.semi="-2">
         <label xml:id="label-L6F3">Trompette en Si♭</label>
         <labelAbbr xml:id="labelabbr-L7F3">Tromp. Si♭</labelAbbr>
         <clef xml:id="clef-L8F3" shape="G" line="2" />
         <keySig xml:id="keysig-L10F3" sig="0" />
         <meterSig xml:id="metersig-L12F3" count="4" unit="4" />
        </staffDef>
       </staffGrp>
       <staffGrp xml:id="p1vmr67i" bar.thru="true" symbol="brace">
        <label xml:id="hgtngpq">Piano</label>
        <labelAbbr xml:id="a1witkfa">Pno.</labelAbbr>
        <staffDef xml:id="staffdef-L3F2" n="2" lines="5">
         <clef xml:id="clef-L8F2" shape="G" line="2" />
         <keySig xml:id="keysig-L10F2" accid="f" mode="major" sig="2f" pname="b" />
         <meterSig xml:id="metersig-L12F2" count="4" unit="4" />
        </staffDef>
        <staffDef xml:id="staffdef-L3F1" n="3" lines="5">
         <clef xml:id="clef-L8F1" shape="F" line="4" />
         <keySig xml:id="keysig-L10F1" accid="f" mode="major" sig="2f" pname="b" />
         <meterSig xml:id="metersig-L12F1" count="4" unit="4" />
        </staffDef>
       </staffGrp>
      </staffGrp>
     </scoreDef>
     <section xml:id="section-L3F1">
      <measure xml:id="measure-L1" n="1">
       <staff xml:id="staff-L3F3" n="1">
        <layer xml:id="layer-L1F3N1" n="1">
         <note xml:id="note-L14F3" dur="1" oct="4" pname="c" accid.ges="n" />
        </layer>
       </staff>
       <staff xml:id="staff-L3F2" n="2">
        <layer xml:id="layer-L1F2N1" n="1">
         <note xml:id="note-L14F2" dur="1" oct="4" pname="b" accid.ges="f" />
        </layer>
       </staff>
       <staff xml:id="staff-L3F1" n="3">
        <layer xml:id="layer-L1F1N1" n="1">
         <note xml:id="note-L14F1" dur="1" oct="3" pname="b" accid.ges="f" />
        </layer>
       </staff>
      </measure>
      <scoreDef xml:id="nvqtu0s">
       <staffGrp xml:id="x8dqey0">
        <staffDef xml:id="ndkclbd" n="1">
         <keySig xml:id="keysig-L16F3" sig="6s" />
        </staffDef>
        <staffDef xml:id="wdmwph6" n="2">
         <keySig xml:id="keysig-L16F2" sig="4s" />
        </staffDef>
        <staffDef xml:id="t6v9jf2" n="3">
         <keySig xml:id="keysig-L16F1" sig="4s" />
        </staffDef>
       </staffGrp>
      </scoreDef>
      <measure xml:id="measure-L15">
       <staff xml:id="staff-L15F3N1" n="1">
        <layer xml:id="layer-L15F3N1" n="1">
         <note xml:id="note-L18F3" dur="1" oct="4" pname="f" accid.ges="s" />
        </layer>
       </staff>
       <staff xml:id="staff-L15F2N1" n="2">
        <layer xml:id="layer-L15F2N1" n="1">
         <note xml:id="note-L18F2" dur="1" oct="5" pname="e" accid.ges="n" />
        </layer>
       </staff>
       <staff xml:id="staff-L15F1N1" n="3">
        <layer xml:id="layer-L15F1N1" n="1">
         <note xml:id="note-L18F1" dur="1" oct="4" pname="e" accid.ges="n" />
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L19" right="dbl">
       <staff xml:id="staff-L19F3N1" n="1">
        <layer xml:id="layer-L19F3N1" n="1">
         <mRest xml:id="mrest-L20F3" />
        </layer>
       </staff>
       <staff xml:id="staff-L19F2N1" n="2">
        <layer xml:id="layer-L19F2N1" n="1">
         <mRest xml:id="mrest-L20F2" />
        </layer>
       </staff>
       <staff xml:id="staff-L19F1N1" n="3">
        <layer xml:id="layer-L19F1N1" n="1">
         <mRest xml:id="mrest-L20F1" />
        </layer>
       </staff>
      </measure>
      <scoreDef xml:id="uj7a9em">
       <staffGrp xml:id="x1z0k603">
        <staffDef xml:id="k1jri4ym" n="1">
         <keySig xml:id="keysig-L22F3" sig="1f" />
        </staffDef>
        <staffDef xml:id="z1bn6u8" n="2">
         <keySig xml:id="keysig-L22F2" sig="3f" />
        </staffDef>
        <staffDef xml:id="q1200uuk" n="3">
         <keySig xml:id="keysig-L22F1" sig="3f" />
        </staffDef>
       </staffGrp>
      </scoreDef>
      <measure xml:id="measure-L21" right="end">
       <staff xml:id="staff-L21F3N1" n="1">
        <layer xml:id="layer-L21F3N1" n="1">
         <note xml:id="note-L24F3" dur="1" oct="4" pname="f" accid.ges="n" />
        </layer>
       </staff>
       <staff xml:id="staff-L21F2N1" n="2">
        <layer xml:id="layer-L21F2N1" n="1">
         <note xml:id="note-L24F2" dur="1" oct="5" pname="e" accid.ges="f" />
        </layer>
       </staff>
       <staff xml:id="staff-L21F1N1" n="3">
        <layer xml:id="layer-L21F1N1" n="1">
         <note xml:id="note-L24F1" dur="1" oct="3" pname="e" accid.ges="f" />
        </layer>
       </staff>
      </measure>
     </section>
    </score>
   </mdiv>
  </body>
 </music>
</mei>

The problem seems more about transposing parts if you are only going to look only at the top part. the top staff part is transposed when written (adding +2 to the circle of fifths). So when the top part key change happens, -2 should be added to its circle-of-fifths when applying the key signature value to the non-transposing part.

@craigsapp craigsapp added the bug For issues describing crashes or unexpected behaviour label May 17, 2025
@rigaux
Copy link

rigaux commented May 17, 2025

Thanks Craig !

Hmmm here is my specific case. My OMR identifies (wrongly) a key signature with one sharp on the piano part at measure 11, and none on the vocal part. This is correctly shown with MuseScore (see copy), but Verovio, when given the MusicXML file, does not show any key signature. Thus, our user cannot correct the situation by removing the wrong key sign.

MuseScore:
Image

Verovio (converting the MusicXML):

Image

The MusicXML file

amant_malheureux.txt

In that case, this is a recognition error. But when we will encounter a transposing instruments, the signatures will be different in the source, and I am afraid they will be unified in the Verovio output after conversion.
What do you think ?

BTW and the analyzed image is here: https://gallica.bnf.fr/ark:/12148/bpt6k382117c/f8.item

@craigsapp
Copy link
Contributor

Yes, that is a different situation requiring independent key signatures for each part (in other words, polytonality). And @rettinghaus can complain about implementation of that case :-).

Correcting errors from OMR in a semantic graphical editor seems difficult. Suppose you are missing a note in the middle of a measure. How would you encode it and how should it be displayed? For example, and original source might have:

Image

But your OMR program (you are creating your own, or using an existing one?) identifies most of the music but misses one note:

Image

How will that be represented in the MusicXML export? Ideally there would be a place holder (forward) in the bottom voice. If there is now, then perhaps the MusicXML data would be more like this:

Image

Where the missing note causes a shift in the music for the second voice/layer. Ideally you would add <forward> with the inferred duration of a quater note. In other words, preserving vertical alignment information in the score.

Preferrably you would use a non-semantic music editor such as SCORE and then after correcting the music, convert the data to a more semantic music representation. SharpEye does something similar with a basic graphical editor with low semantics where corrections are done and then exported to MusicXML.


The source has an interesting alternate for vocal tenor clef:

Image

(two dots on the second-to-bottom staff line) which is equivalent to:

Image

Looking at measure 11 in the source:

Image

https://gallica.bnf.fr/ark:/12148/bpt6k382117c/f5.item.zoom

I am wondering how a g-sharp on a note can be interpreted as an f-sharp key signature. Then the second note in the piano RH (F#4) has its sharp removed since the sharp is being assigned from the false key signature... So interpretation of accidentals also becomes a problem (fixing a key signature in Verovio will necessitate fixing all of the following accidentals on F.


In a previous example:

Image

The semantics of this line of music is tricky. Ideally OMR would notice the blank staff lines on the bottom staff, and then split the notes across the two staves for two voices based on the stem directions in this case (one voice in the top staff for the right hand and one voice for the left hand in the bottom staff). Then in MEI, the LH notes on the bottom staff can be displayed on the top staff although they are attached to the bottom staff (measures 8—14):

Image
Click to view MEI data for above example
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/5.1/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/5.1/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.1">
 <meiHead>
  <fileDesc>
   <titleStmt>
    <title>Mouvᵗ de Valse.</title>
   </titleStmt>
   <pubStmt>
   </pubStmt>
  </fileDesc>
  <encodingDesc>
   <appInfo>
    <application isodate="2025-05-17T11:31:38" version="5.2.0-dev-4660ee3-dirty">
     <name>Verovio</name>
     <p>Transcoded from Humdrum</p>
    </application>
   </appInfo>
  </encodingDesc>
  <workList>
   <work xml:id="work0_encoded" type="encoded">
    <title type="uniform">
     <titlePart type="movementName" analog="humdrum:OMD">Mouvᵗ de Valse.</titlePart>
    </title>
   </work>
  </workList>
 </meiHead>
 <music decls="#work0_encoded">
  <body>
   <mdiv xml:id="payjwf7">
    <score xml:id="imx9pzp">
     <scoreDef xml:id="gb1tecu" tempo.dist="3vu">
      <staffGrp xml:id="o381rg3" bar.thru="true" symbol="brace">
       <label xml:id="a1a9qrvb">Piano</label>
       <staffDef xml:id="staffdef-L2F2" n="1" lines="5">
        <clef xml:id="clef-L4F2" shape="G" line="2" />
        <keySig xml:id="keysig-L6F2" sig="2f" />
        <meterSig xml:id="metersig-L7F2" count="3" unit="4" />
        <instrDef xml:id="k8zj7c3" midi.instrnum="0" midi.instrname="Acoustic_Grand_Piano" />
       </staffDef>
       <staffDef xml:id="staffdef-L2F1" n="2" lines="5">
        <clef xml:id="clef-L4F1" shape="F" line="4" />
        <keySig xml:id="keysig-L6F1" sig="2f" />
        <meterSig xml:id="metersig-L7F1" count="3" unit="4" />
        <instrDef xml:id="h1xjlvbd" midi.instrnum="0" midi.instrname="Acoustic_Grand_Piano" />
       </staffDef>
      </staffGrp>
     </scoreDef>
     <section xml:id="section-L2F1">
      <measure xml:id="measure-L1" n="1">
       <staff xml:id="staff-L2F2" n="1">
        <layer xml:id="layer-L1F2N1" n="1">
         <chord xml:id="chord-L9F2" type="placed" dots="1" dur="2" stem.dir="up">
          <note xml:id="note-L9F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L9F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L9F2" artic="acc" place="above" />
         </chord>
        </layer>
       </staff>
       <staff xml:id="staff-L2F1" n="2">
        <layer xml:id="layer-L1F1N1" n="1">
         <mRest xml:id="mrest-L9F1" />
        </layer>
       </staff>
       <tempo xml:id="tempo-L1F1" staff="1" tstamp="1">Mouvᵗ de Valse.</tempo>
       <dynam xml:id="dynam-L9F3" place="between" staff="1 2" tstamp="1">f</dynam>
      </measure>
      <measure xml:id="measure-L10" n="2">
       <staff xml:id="staff-L10F2N1" n="1">
        <layer xml:id="layer-L10F2N1" n="1">
         <mRest xml:id="mrest-L11F2" />
        </layer>
       </staff>
       <staff xml:id="staff-L10F1N1" n="2">
        <layer xml:id="layer-L10F1N1" n="1">
         <chord xml:id="chord-L11F1" dots="1" dur="2">
          <note xml:id="note-L11F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L11F1S2" oct="4" pname="a" accid.ges="n" />
          <artic xml:id="artic-L11F1" artic="acc" place="below" />
         </chord>
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L12" n="3">
       <staff xml:id="staff-L12F2N1" n="1">
        <layer xml:id="layer-L12F2N1" n="1">
         <chord xml:id="chord-L13F2" type="placed" dur="2" stem.dir="up">
          <note xml:id="note-L13F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L13F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L13F2" artic="acc" place="above" />
         </chord>
         <chord xml:id="chord-L14F2" type="placed" dur="4" stem.dir="up">
          <note xml:id="note-L14F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L14F2S2" oct="5" pname="e" accid.ges="f" />
         </chord>
        </layer>
       </staff>
       <staff xml:id="staff-L12F1N1" n="2">
        <layer xml:id="layer-L12F1N1" n="1">
         <mRest xml:id="mrest-L13F1" />
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L15" n="4">
       <staff xml:id="staff-L15F2N1" n="1">
        <layer xml:id="layer-L15F2N1" n="1">
         <mRest xml:id="mrest-L16F2" />
        </layer>
       </staff>
       <staff xml:id="staff-L15F1N1" n="2">
        <layer xml:id="layer-L15F1N1" n="1">
         <chord xml:id="chord-L16F1" dur="2">
          <note xml:id="note-L16F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L16F1S2" oct="4" pname="a" accid.ges="n" />
          <artic xml:id="artic-L16F1" artic="acc" place="below" />
         </chord>
         <chord xml:id="chord-L17F1" dur="4">
          <note xml:id="note-L17F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L17F1S2" oct="4" pname="a" accid.ges="n" />
         </chord>
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L18" n="5">
       <staff xml:id="staff-L18F2N1" n="1">
        <layer xml:id="layer-L18F2N1" n="1">
         <beam xml:id="beam-L19F2-L20F2" type="placed">
          <chord xml:id="chord-L19F2" dur="8" stem.dir="up">
           <note xml:id="note-L19F2S1" oct="4" pname="a" accid.ges="n" />
           <note xml:id="note-L19F2S2" oct="5" pname="e" accid.ges="f" />
           <artic xml:id="artic-L19F2" artic="acc" place="above" />
          </chord>
          <chord xml:id="chord-L20F2" dur="8" stem.dir="up">
           <note xml:id="note-L20F2S1" oct="4" pname="a" accid.ges="n" />
           <note xml:id="note-L20F2S2" oct="5" pname="e" accid.ges="f" />
          </chord>
         </beam>
         <chord xml:id="chord-L21F2" type="placed" dur="4" stem.dir="up">
          <note xml:id="note-L21F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L21F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L21F2" artic="stacc" place="above" />
         </chord>
         <rest xml:id="rest-L22F2" dur="4" />
        </layer>
       </staff>
       <staff xml:id="staff-L18F1N1" n="2">
        <layer xml:id="layer-L18F1N1" n="1">
         <rest xml:id="rest-L19F1" dur="2" />
         <chord xml:id="chord-L22F1" dur="4">
          <note xml:id="note-L22F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L22F1S2" oct="4" pname="a" accid.ges="n" />
          <artic xml:id="artic-L22F1" artic="stacc" />
         </chord>
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L23" n="5">
       <staff xml:id="staff-L23F2N1" n="1">
        <layer xml:id="layer-L23F2N1" n="1">
         <beam xml:id="beam-L24F2-L25F2" type="placed">
          <chord xml:id="chord-L24F2" dur="8" stem.dir="up">
           <note xml:id="note-L24F2S1" oct="4" pname="a" accid.ges="n" />
           <note xml:id="note-L24F2S2" oct="5" pname="e" accid.ges="f" />
           <artic xml:id="artic-L24F2" artic="acc" place="above" />
          </chord>
          <chord xml:id="chord-L25F2" dur="8" stem.dir="up">
           <note xml:id="note-L25F2S1" oct="4" pname="a" accid.ges="n" />
           <note xml:id="note-L25F2S2" oct="5" pname="e" accid.ges="f" />
          </chord>
         </beam>
         <chord xml:id="chord-L26F2" type="placed" dur="4" stem.dir="up">
          <note xml:id="note-L26F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L26F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L26F2" artic="stacc" place="above" />
         </chord>
         <rest xml:id="rest-L27F2" dur="4" />
        </layer>
       </staff>
       <staff xml:id="staff-L23F1N1" n="2">
        <layer xml:id="layer-L23F1N1" n="1">
         <rest xml:id="rest-L24F1" dur="2" />
         <chord xml:id="chord-L27F1" dur="4">
          <note xml:id="note-L27F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L27F1S2" oct="4" pname="a" accid.ges="n" />
          <artic xml:id="artic-L27F1" artic="stacc" />
         </chord>
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L28" right="dbl" n="7">
       <staff xml:id="staff-L28F2N1" n="1">
        <layer xml:id="layer-L28F2N1" n="1">
         <chord xml:id="chord-L29F2" type="placed" dur="4" stem.dir="up">
          <note xml:id="note-L29F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L29F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L29F2" artic="stacc" place="above" />
         </chord>
         <rest xml:id="rest-L30F2" dur="4" />
         <chord xml:id="chord-L31F2" type="placed" dur="4" stem.dir="up">
          <note xml:id="note-L31F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L31F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L31F2" artic="stacc" place="above" />
         </chord>
        </layer>
       </staff>
       <staff xml:id="staff-L28F1N1" n="2">
        <layer xml:id="layer-L28F1N1" n="1">
         <rest xml:id="rest-L29F1" dur="4" />
         <chord xml:id="chord-L30F1" dur="4">
          <note xml:id="note-L30F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L30F1S2" oct="4" pname="a" accid.ges="n" />
          <artic xml:id="artic-L30F1" artic="stacc" />
         </chord>
         <rest xml:id="rest-L31F1" dur="4" />
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L32">
       <staff xml:id="staff-L32F2N1" n="1">
        <layer xml:id="layer-L32F2N1" n="1">
         <chord xml:id="chord-L33F2" type="placed" dots="1" dur="2" stem.dir="up">
          <note xml:id="note-L33F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L33F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L33F2" artic="acc" place="above" />
         </chord>
        </layer>
       </staff>
       <staff xml:id="staff-L32F1N1" n="2">
        <layer xml:id="layer-L32F1N1" n="1">
         <mRest xml:id="mrest-L33F1" visible="false" />
        </layer>
       </staff>
       <dynam xml:id="dynam-L33F3" place="between" staff="1 2" tstamp="1">f</dynam>
      </measure>
      <measure xml:id="measure-L34" n="2">
       <staff xml:id="staff-L34F2N1" n="1">
        <layer xml:id="layer-L34F2N1" n="1">
         <mRest xml:id="mrest-L35F2" visible="false" />
        </layer>
       </staff>
       <staff xml:id="staff-L34F1N1" n="2">
        <layer xml:id="layer-L34F1N1" n="1">
         <chord xml:id="chord-L35F1" dots="1" dur="2" staff="1" stem.dir="down">
          <note xml:id="note-L35F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L35F1S2" oct="4" pname="a" accid.ges="n" />
          <artic xml:id="artic-L35F1" artic="acc" place="below" />
         </chord>
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L36" n="3">
       <staff xml:id="staff-L36F2N1" n="1">
        <layer xml:id="layer-L36F2N1" n="1">
         <chord xml:id="chord-L37F2" type="placed" dur="2" stem.dir="up">
          <note xml:id="note-L37F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L37F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L37F2" artic="acc" place="above" />
         </chord>
         <chord xml:id="chord-L38F2" type="placed" dur="4" stem.dir="up">
          <note xml:id="note-L38F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L38F2S2" oct="5" pname="e" accid.ges="f" />
         </chord>
        </layer>
       </staff>
       <staff xml:id="staff-L36F1N1" n="2">
        <layer xml:id="layer-L36F1N1" n="1">
         <mRest xml:id="mrest-L37F1" visible="false" />
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L39" n="4">
       <staff xml:id="staff-L39F2N1" n="1">
        <layer xml:id="layer-L39F2N1" n="1">
         <mRest xml:id="mrest-L40F2" visible="false" />
        </layer>
       </staff>
       <staff xml:id="staff-L39F1N1" n="2">
        <layer xml:id="layer-L39F1N1" n="1">
         <chord xml:id="chord-L40F1" dur="2" staff="1" stem.dir="down">
          <note xml:id="note-L40F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L40F1S2" oct="4" pname="a" accid.ges="n" />
          <artic xml:id="artic-L40F1" artic="acc" place="below" />
         </chord>
         <chord xml:id="chord-L41F1" dur="4" staff="1" stem.dir="down">
          <note xml:id="note-L41F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L41F1S2" oct="4" pname="a" accid.ges="n" />
         </chord>
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L42" n="5">
       <staff xml:id="staff-L42F2N1" n="1">
        <layer xml:id="layer-L42F2N1" n="1">
         <beam xml:id="beam-L43F2-L44F2" type="placed">
          <chord xml:id="chord-L43F2" dur="8" stem.dir="up">
           <note xml:id="note-L43F2S1" oct="4" pname="a" accid.ges="n" />
           <note xml:id="note-L43F2S2" oct="5" pname="e" accid.ges="f" />
           <artic xml:id="artic-L43F2" artic="acc" place="above" />
          </chord>
          <chord xml:id="chord-L44F2" dur="8" stem.dir="up">
           <note xml:id="note-L44F2S1" oct="4" pname="a" accid.ges="n" />
           <note xml:id="note-L44F2S2" oct="5" pname="e" accid.ges="f" />
          </chord>
         </beam>
         <chord xml:id="chord-L45F2" type="placed" dur="4" stem.dir="up">
          <note xml:id="note-L45F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L45F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L45F2" artic="stacc" place="above" />
         </chord>
         <space xml:id="space-L46F2" dur="4" />
        </layer>
       </staff>
       <staff xml:id="staff-L42F1N1" n="2">
        <layer xml:id="layer-L42F1N1" n="1">
         <space xml:id="space-L43F1" dur="2" />
         <chord xml:id="chord-L46F1" dur="4" staff="1" stem.dir="down">
          <note xml:id="note-L46F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L46F1S2" oct="4" pname="a" accid.ges="n" />
          <artic xml:id="artic-L46F1" artic="stacc" />
         </chord>
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L47" n="5">
       <staff xml:id="staff-L47F2N1" n="1">
        <layer xml:id="layer-L47F2N1" n="1">
         <beam xml:id="beam-L48F2-L49F2" type="placed">
          <chord xml:id="chord-L48F2" dur="8" stem.dir="up">
           <note xml:id="note-L48F2S1" oct="4" pname="a" accid.ges="n" />
           <note xml:id="note-L48F2S2" oct="5" pname="e" accid.ges="f" />
           <artic xml:id="artic-L48F2" artic="acc" place="above" />
          </chord>
          <chord xml:id="chord-L49F2" dur="8" stem.dir="up">
           <note xml:id="note-L49F2S1" oct="4" pname="a" accid.ges="n" />
           <note xml:id="note-L49F2S2" oct="5" pname="e" accid.ges="f" />
          </chord>
         </beam>
         <chord xml:id="chord-L50F2" type="placed" dur="4" stem.dir="up">
          <note xml:id="note-L50F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L50F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L50F2" artic="stacc" place="above" />
         </chord>
         <space xml:id="space-L51F2" dur="4" />
        </layer>
       </staff>
       <staff xml:id="staff-L47F1N1" n="2">
        <layer xml:id="layer-L47F1N1" n="1">
         <space xml:id="space-L48F1" dur="2" />
         <chord xml:id="chord-L51F1" dur="4" staff="1" stem.dir="down">
          <note xml:id="note-L51F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L51F1S2" oct="4" pname="a" accid.ges="n" />
          <artic xml:id="artic-L51F1" artic="stacc" />
         </chord>
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L52" n="7">
       <staff xml:id="staff-L52F2N1" n="1">
        <layer xml:id="layer-L52F2N1" n="1">
         <chord xml:id="chord-L53F2" type="placed" dur="4" stem.dir="up">
          <note xml:id="note-L53F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L53F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L53F2" artic="stacc" place="above" />
         </chord>
         <space xml:id="space-L54F2" dur="4" />
         <chord xml:id="chord-L55F2" type="placed" dur="4" stem.dir="up">
          <note xml:id="note-L55F2S1" oct="4" pname="a" accid.ges="n" />
          <note xml:id="note-L55F2S2" oct="5" pname="e" accid.ges="f" />
          <artic xml:id="artic-L55F2" artic="stacc" place="above" />
         </chord>
        </layer>
       </staff>
       <staff xml:id="staff-L52F1N1" n="2">
        <layer xml:id="layer-L52F1N1" n="1">
         <space xml:id="space-L53F1" dur="4" />
         <chord xml:id="chord-L54F1" dur="4" staff="1" stem.dir="down">
          <note xml:id="note-L54F1S1" oct="4" pname="d" accid.ges="n" />
          <note xml:id="note-L54F1S2" oct="4" pname="a" accid.ges="n" />
          <artic xml:id="artic-L54F1" artic="stacc" />
         </chord>
         <space xml:id="space-L55F1" dur="4" />
        </layer>
       </staff>
      </measure>
     </section>
    </score>
   </mdiv>
  </body>
 </music>
</mei>

Somewhat related and of interest to you: The Polish Scores in Open Access project has 60000 pages of music transcription (8000 scores containing 12000000 notes):

https://polishmusic.org

All of the scores has links to IIIF scans of the source editions, with 1000 of them linked at the system level, click on the "I" button for scores where the IIIF images have been linked to the transcriptions at the system level:

Image

such as:

https://polishscores.org/?id=18xx:3726

Double clicking on a note in the score will bring up the system image from the full page:

Image

IIIF URL: https://zas.bn.org.pl/iiif/74775867/86210581.tif/286,409,2656,1027/full/0/default.jpg

Notation in verovio:

Image

Humdrum data:

https://github.com/pl-wnifc/humdrum-polish-scores/blob/main/pl-wn/kern/pl-wn--mus-iii-94-168_zelenski-wladyslaw--reverie-op-48.krn#L38

Line 38 has bounding box information for the two staves:

*xywh-2:286,409,2656,1027	

Which means image 2 of the IIIF document, bounding box 286,409,2656,1027 (xywh),

And the manifest is on line 22:

https://polona2.pl/iiif/item/NzQ3NzU4Njc/manifest.json

Are used together to generate the IIIF image of the music:

https://zas.bn.org.pl/iiif/74775867/86210581.tif/286,409,2656,1027/full/0/default.jpg

Recent paper on the project in JNMR: https://www.tandfonline.com/doi/full/10.1080/09298215.2025.2487093

@rigaux
Copy link

rigaux commented May 17, 2025

Woooh a lot to say.

Yes we are producing our own OMR system. Yes, distinction of key signatures and accidentals still requires some work (we are almost there). Regarding our correction method: we provide interfaces to correct the output of OMR, but we do NOT allow for insertion of any object. The prototype is in place in case to want to have a look (https://collabscore.cnam.fr/, fully in French, sorry).

Regarding the example (Danse macabre), our system preserves the staff of the notes/silences, regardless of the voice (a voice can be distributed on all the staves of a part).

I will be glad to look at your examples and paper. And your help and advices are always much appreciated, hope we will soon have an opportunity for a face to face discussion. Thanks for all !

@lpugin lpugin added feature request and removed bug For issues describing crashes or unexpected behaviour labels May 18, 2025
@lpugin lpugin changed the title Verovio displaying from key signatures Take into account key changes not only from the first staff May 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants