Skip to content
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

Add grace and arpeggios notes to the timemap #3956

Merged
merged 13 commits into from
Feb 18, 2025
Merged

Conversation

lpugin
Copy link
Contributor

@lpugin lpugin commented Feb 16, 2025

This PR adds the grace notes to the timemap. Fixes #3909

A new functor has been added to do the gracenotes adjustment when preparing the timemap instead of doing it when producing the MIDI. The MIDI output is simplified and uses the timemap values.

Marked as draft for now since I will do the same for arpeggios and tablature note extension.

MEI

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0">
   <meiHead>
      <fileDesc>
         <titleStmt>
            <title>Grace notes example</title>
         </titleStmt>
         <pubStmt>
            <date>2017-05-09</date>
         </pubStmt>
      </fileDesc>
      <encodingDesc>
         <appInfo>
            <application version="unknown">
               <name>Verovio</name>
            </application>
         </appInfo>
      </encodingDesc>
   </meiHead>
   <music>
      <body>
         <mdiv xml:id="morcdtg">
            <score xml:id="s1hznare">
               <scoreDef xml:id="s77ltdx">
                  <staffGrp xml:id="s1fexet9">
                     <staffDef xml:id="sfdbjo2" n="1" lines="5" clef.shape="G" clef.line="2" key.mode="major" keysig="2s" />
                  </staffGrp>
               </scoreDef>
               <section xml:id="s9qtecc">
                  <measure xml:id="mfrn3u3" n="1">
                     <staff xml:id="szb2nxd" n="1">
                        <layer xml:id="l1tesglb" n="1">
                           <note xml:id="no43wyy" dur="8" oct="4" pname="b" grace="acc" />
                           <note xml:id="n12ubxu0" dur="2" oct="4" pname="d" />
                           <note xml:id="n1bor2nx" dur="8" oct="4" pname="a" grace="acc" />
                           <note xml:id="nwfmhjk" dur="4" oct="4" pname="d" />
                           <note xml:id="nqu5764" dur="8" oct="4" pname="g" grace="acc" />
                           <note xml:id="n1omecu9" dur="4" oct="4" pname="d" />
                        </layer>
                     </staff>
                  </measure>
                  <measure xml:id="m1bmgix5" n="2">
                     <staff xml:id="s1vplvve" n="1">
                        <layer xml:id="l1w4k03w" n="1">
                           <beam>
                              <note xml:id="nddv0ri" dur="8" oct="4" pname="f" grace="acc" />
                              <note xml:id="nddv0ri" dur="8" oct="4" pname="a" grace="acc" />
                           </beam>
                           <note xml:id="n1wugmch" dur="4" oct="4" pname="g" />
                           <note xml:id="n3838hl" dur="8" oct="4" pname="e" grace="acc" />
                           <note xml:id="n1f2gd5u" dur="4" oct="4" pname="d" />
                           <note xml:id="n1vifptt" dur="8" oct="4" pname="e" grace="acc" />
                           <note xml:id="ntm0bnk" dur="2" oct="5" pname="c" />
                        </layer>
                     </staff>
                  </measure>
                  <measure xml:id="mpd1qnq" n="3">
                     <staff xml:id="s1izu1ut" n="1">
                        <layer xml:id="l1jgw543" n="1">
                           <note xml:id="nk6zpsf" dur="8" oct="4" pname="f" grace="acc" />
                           <note xml:id="rorcdtg" dur="4" oct="5" pname="c" />
                           <note xml:id="n12lfalk" dur="8" oct="4" pname="g" grace="unacc" />
                           <note xml:id="nrs4lhq" dur="4" oct="5" pname="c" />
                           <note xml:id="n18wlm3l" dur="8" oct="4" pname="a" grace="unacc" />
                           <note xml:id="n1jy649" dur="4" oct="5" pname="c" />
                           <note xml:id="n19c8hp6" dur="8" oct="4" pname="b" grace="acc" />
                           <note xml:id="nwp1uti" dur="4" oct="5" pname="c" />
                        </layer>
                     </staff>
                  </measure>
                  <measure xml:id="m1nmk4lp" right="end" n="4">
                     <staff xml:id="sa3bpe5" n="1">
                        <layer xml:id="l1nde9a8" n="1">
                           <note xml:id="n1w0ysrk" dur="8" oct="4" pname="a" grace="acc" />
                           <note xml:id="n1u30b27" dur="4" oct="5" pname="c" />
                           <beam xml:id="b1yx9lr3">
                              <note xml:id="n1pe3h1n" dur="8" oct="5" pname="g" grace="acc" />
                              <note xml:id="n12jrufd" dur="8" oct="5" pname="c" grace="acc" />
                              <note xml:id="nuliurc" dur="8" oct="5" pname="d" grace="acc" />
                           </beam>
                           <note xml:id="nfs0gck" dur="4" oct="5" pname="c" />
                           <beam xml:id="b17glthj">
                              <note xml:id="ndd650g" dur="8" oct="6" pname="d" grace="acc" />
                              <note xml:id="n4l117g" dur="8" oct="6" pname="c" grace="acc" />
                              <note xml:id="ncuq7yy" dur="8" oct="5" pname="b" grace="acc" />
                              <note xml:id="neh1osz" dur="8" oct="5" pname="a" grace="acc" />
                              <note xml:id="noto51m" dur="8" oct="5" pname="g" grace="acc" />
                              <note xml:id="nc7avtd" dur="8" oct="5" pname="f" grace="acc" />
                              <note xml:id="nloeqsd" dur="8" oct="5" pname="e" grace="acc" />
                              <note xml:id="n7nve8j" dur="8" oct="5" pname="d" grace="acc" />
                              <note xml:id="nljpcte" dur="16" oct="5" pname="c" grace="acc" />
                              <note xml:id="nrwsesl" dur="16" oct="4" pname="b" grace="acc" />
                              <note xml:id="n14a1l9r" dur="16" oct="4" pname="a" grace="acc" accid="f" />
                              <note xml:id="ngzg16q" dur="16" oct="5" pname="c" grace="acc" />
                              <note xml:id="n1ua9fxl" dur="32" oct="4" pname="b" grace="acc" />
                              <note xml:id="n1f0x1st" dur="32" oct="4" pname="f" grace="acc" />
                              <note xml:id="ntxenxm" dur="64" oct="4" pname="g" grace="acc" />
                              <note xml:id="n12egnpa" dur="64" oct="4" pname="c" grace="acc" />
                           </beam>
                           <note xml:id="n11pynnw" dur="2" oct="4" pname="d" />
                        </layer>
                     </staff>
                  </measure>
               </section>
            </score>
         </mdiv>
      </body>
   </music>
</mei>

Timemap

[
	{
		"on": [
			"no43wyy" 
		],
		"qstamp": 0,
		"tempo": 120,
		"tstamp": 0 
	},
	{
		"off": [
			"no43wyy" 
		],
		"on": [
			"n12ubxu0" 
		],
		"qstamp": 1,
		"tstamp": 500 
	},
	{
		"off": [
			"n12ubxu0" 
		],
		"on": [
			"n1bor2nx" 
		],
		"qstamp": 2,
		"tstamp": 1000 
	},
	{
		"off": [
			"n1bor2nx" 
		],
		"on": [
			"nwfmhjk" 
		],
		"qstamp": 2.5,
		"tstamp": 1250 
	},
	{
		"off": [
			"nwfmhjk" 
		],
		"on": [
			"nqu5764" 
		],
		"qstamp": 3,
		"tstamp": 1500 
	},
	{
		"off": [
			"nqu5764" 
		],
		"on": [
			"n1omecu9" 
		],
		"qstamp": 3.5,
		"tstamp": 1750 
	},
	{
		"off": [
			"n1omecu9" 
		],
		"on": [
			"nddv0ri" 
		],
		"qstamp": 4,
		"tstamp": 2000 
	},
	{
		"off": [
			"nddv0ri" 
		],
		"on": [
			"nddv0ri" 
		],
		"qstamp": 4.25,
		"tstamp": 2125 
	},
	{
		"off": [
			"nddv0ri" 
		],
		"on": [
			"n1wugmch" 
		],
		"qstamp": 4.5,
		"tstamp": 2250 
	},
	{
		"off": [
			"n1wugmch" 
		],
		"on": [
			"n3838hl" 
		],
		"qstamp": 5,
		"tstamp": 2500 
	},
	{
		"off": [
			"n3838hl" 
		],
		"on": [
			"n1f2gd5u" 
		],
		"qstamp": 5.5,
		"tstamp": 2750 
	},
	{
		"off": [
			"n1f2gd5u" 
		],
		"on": [
			"n1vifptt" 
		],
		"qstamp": 6,
		"tstamp": 3000 
	},
	{
		"off": [
			"n1vifptt" 
		],
		"on": [
			"ntm0bnk" 
		],
		"qstamp": 7,
		"tstamp": 3500 
	},
	{
		"off": [
			"ntm0bnk" 
		],
		"on": [
			"nk6zpsf" 
		],
		"qstamp": 8,
		"tstamp": 4000 
	},
	{
		"off": [
			"nk6zpsf" 
		],
		"on": [
			"rorcdtg" 
		],
		"qstamp": 8.5,
		"tstamp": 4250 
	},
	{
		"on": [
			"n12lfalk" 
		],
		"qstamp": 8.984375,
		"tstamp": 4492 
	},
	{
		"off": [
			"rorcdtg",
			"n12lfalk" 
		],
		"on": [
			"nrs4lhq" 
		],
		"qstamp": 9,
		"tstamp": 4500 
	},
	{
		"on": [
			"n18wlm3l" 
		],
		"qstamp": 9.984375,
		"tstamp": 4992 
	},
	{
		"off": [
			"nrs4lhq",
			"n18wlm3l" 
		],
		"on": [
			"n1jy649" 
		],
		"qstamp": 10,
		"tstamp": 5000 
	},
	{
		"off": [
			"n1jy649" 
		],
		"on": [
			"n19c8hp6" 
		],
		"qstamp": 11,
		"tstamp": 5500 
	},
	{
		"off": [
			"n19c8hp6" 
		],
		"on": [
			"nwp1uti" 
		],
		"qstamp": 11.5,
		"tstamp": 5750 
	},
	{
		"off": [
			"nwp1uti" 
		],
		"on": [
			"n1w0ysrk" 
		],
		"qstamp": 12,
		"tstamp": 6000 
	},
	{
		"off": [
			"n1w0ysrk" 
		],
		"on": [
			"n1u30b27" 
		],
		"qstamp": 12.5,
		"tstamp": 6250 
	},
	{
		"off": [
			"n1u30b27" 
		],
		"on": [
			"n1pe3h1n" 
		],
		"qstamp": 13,
		"tstamp": 6500 
	},
	{
		"off": [
			"n1pe3h1n" 
		],
		"on": [
			"n12jrufd" 
		],
		"qstamp": 13.16666666666667,
		"tstamp": 6583 
	},
	{
		"off": [
			"n12jrufd" 
		],
		"on": [
			"nuliurc" 
		],
		"qstamp": 13.33333333333333,
		"tstamp": 6667 
	},
	{
		"off": [
			"nuliurc" 
		],
		"on": [
			"nfs0gck" 
		],
		"qstamp": 13.5,
		"tstamp": 6750 
	},
	{
		"off": [
			"nfs0gck" 
		],
		"on": [
			"ndd650g" 
		],
		"qstamp": 14,
		"tstamp": 7000 
	},
	{
		"off": [
			"ndd650g" 
		],
		"on": [
			"n4l117g" 
		],
		"qstamp": 14.0625,
		"tstamp": 7031 
	},
	{
		"off": [
			"n4l117g" 
		],
		"on": [
			"ncuq7yy" 
		],
		"qstamp": 14.125,
		"tstamp": 7063 
	},
	{
		"off": [
			"ncuq7yy" 
		],
		"on": [
			"neh1osz" 
		],
		"qstamp": 14.1875,
		"tstamp": 7094 
	},
	{
		"off": [
			"neh1osz" 
		],
		"on": [
			"noto51m" 
		],
		"qstamp": 14.25,
		"tstamp": 7125 
	},
	{
		"off": [
			"noto51m" 
		],
		"on": [
			"nc7avtd" 
		],
		"qstamp": 14.3125,
		"tstamp": 7156 
	},
	{
		"off": [
			"nc7avtd" 
		],
		"on": [
			"nloeqsd" 
		],
		"qstamp": 14.375,
		"tstamp": 7188 
	},
	{
		"off": [
			"nloeqsd" 
		],
		"on": [
			"n7nve8j" 
		],
		"qstamp": 14.4375,
		"tstamp": 7219 
	},
	{
		"off": [
			"n7nve8j" 
		],
		"on": [
			"nljpcte" 
		],
		"qstamp": 14.5,
		"tstamp": 7250 
	},
	{
		"off": [
			"nljpcte" 
		],
		"on": [
			"nrwsesl" 
		],
		"qstamp": 14.5625,
		"tstamp": 7281 
	},
	{
		"off": [
			"nrwsesl" 
		],
		"on": [
			"n14a1l9r" 
		],
		"qstamp": 14.625,
		"tstamp": 7313 
	},
	{
		"off": [
			"n14a1l9r" 
		],
		"on": [
			"ngzg16q" 
		],
		"qstamp": 14.6875,
		"tstamp": 7344 
	},
	{
		"off": [
			"ngzg16q" 
		],
		"on": [
			"n1ua9fxl" 
		],
		"qstamp": 14.75,
		"tstamp": 7375 
	},
	{
		"off": [
			"n1ua9fxl" 
		],
		"on": [
			"n1f0x1st" 
		],
		"qstamp": 14.8125,
		"tstamp": 7406 
	},
	{
		"off": [
			"n1f0x1st" 
		],
		"on": [
			"ntxenxm" 
		],
		"qstamp": 14.875,
		"tstamp": 7438 
	},
	{
		"off": [
			"ntxenxm" 
		],
		"on": [
			"n12egnpa" 
		],
		"qstamp": 14.9375,
		"tstamp": 7469 
	},
	{
		"off": [
			"n12egnpa" 
		],
		"on": [
			"n11pynnw" 
		],
		"qstamp": 15,
		"tstamp": 7500 
	},
	{
		"off": [
			"n11pynnw" 
		],
		"qstamp": 16,
		"tstamp": 8000 
	} 
] 

Example use of the timemap with grace note highlighting (new)

Screen.Recording.2025-02-16.at.11.49.02.mov

@lpugin lpugin requested a review from brdvd February 16, 2025 10:59
@craigsapp
Copy link
Contributor

I am presuming that grace notes are given a non-zero duration in the MIDI file? Otherwise there can be problems with MIDI playback.

@rettinghaus
Copy link
Contributor

That makes me wonder if this would be a chance to add support for @grace.time?

@lpugin
Copy link
Contributor Author

lpugin commented Feb 16, 2025

That makes me wonder if this would be a chance to add support for @grace.time?

I can add it for acc since this looks reasonably easy.

@craigsapp
Copy link
Contributor

Having it for acc would be great! @rettinghaus implemented acc as taking 1/2 of the duration of the next note, where I want it to take the visual duration of the grace note. Then we can both be happy 😄

@lpugin
Copy link
Contributor Author

lpugin commented Feb 16, 2025

@grace.time is a percent, I hope you are still going to be happy with that ... 😄

@craigsapp
Copy link
Contributor

Good enough 😛

Copy link
Contributor

@brdvd brdvd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks quite good, thank you! There is one issue with the grace note duration of unaccented grace notes. I don't understand if this was changed deliberately or accidentally.

@lpugin lpugin marked this pull request as ready for review February 17, 2025 10:03
@lpugin lpugin requested a review from brdvd February 17, 2025 10:03
@lpugin lpugin changed the title Add grace notes to the timemap Add grace and arpeggios notes to the timemap Feb 17, 2025
@lpugin lpugin requested a review from ahankinson February 18, 2025 08:14
@lpugin
Copy link
Contributor Author

lpugin commented Feb 18, 2025

Should be good to merge

@rettinghaus rettinghaus requested a review from brdvd February 18, 2025 09:30
@@ -73,6 +73,7 @@ namespace vrv {
#define MIDI_TEMPO 120

#define UNACC_GRACENOTE_DUR 27 // in milliseconds
#define UNACC_GRACENOTE_FRACTION Fraction(1, 2024)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is 2024 correct? 1024 or 2048 would make more sense?

@ahankinson ahankinson merged commit 8b6f98c into develop Feb 18, 2025
9 checks passed
@lpugin lpugin deleted the develop-timemap branch February 18, 2025 12:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Grace note missing in time map
5 participants