Three Voices Per Stave

439 views
Skip to first unread message

LarryKu

unread,
Feb 5, 2013, 11:35:00 AM2/5/13
to vex...@googlegroups.com
In Dan Ringwalt MusciXML post the topic of three voices per stave came up. Rather than hi-jack that post, I decided to start a new one. Last night I decided to test vexflow to see what would happen if three voices were added to a stave. I was quite surprised at the results. In the sample below, I tried to duplicate two of the most common occurrences that I have run into.  The only change to vexflow source was to comment out the 2 voice check in modifiercontext.js.

#1: Notes need to be offset to avoid collision between the voices, and stems from one voice drawing into a second voice (beat 1). The middle voice stem on beat 1 extends too far and overlaps the lower voice. There needs to be a way to shorten stems when needed.

#2: Middle voice counter melody with note in between notes of another voice that must be offset (beats 1 & 3).  As you can see the notes in the middle voice were offset when needed. I wasn't expecting that, but it happened.There probably should be a bit more offset of the stems to get some separation. Also, the dot placement is not correct.

There are more cases, but these are the two most frequent. Overall, implementing three voice capability shouldn't be that difficult.

Comments welcome.
Vexflow-Three-Voices.png

Michael Scott Cuthbert

unread,
Feb 5, 2013, 12:04:14 PM2/5/13
to <vexflow@googlegroups.com>
As far as I know, no music editor correctly imports 3 or more voices per staff without needing human hinting, so the creators of Vexflow shouldn't be hard on themselves if it's not doing it right.  The ideal result in the images currently given (though it doesn't work for everything) would be to have the middle voice use a very short stem so that the beams don't hit the third voice.  It's very hard to do this right in cases where all three voices are close to each other.  One of the notation books (not Behind Bars. Blanking right now) has examples of effective engraving of up to five(!) voices on a staff.

btw -- one thing that might be too late to change now, but has always bothered me a bit in Vexflow: if American English is used for duration types (w, h, q) then the American singular "staff" (where "stave" is almost never used in the singular) would be better than stave.

People on this list might be interested to see that a new release of neoScores came out yesterday, which also has a fast HTML5 notation rendering engine.  Very nice, but not nearly as open a project as Vexflow.  Their MusicXML rendering is quite good though.

Best,
Myke


---                                                             ---
Michael Scott Cuthbert 

Homer A. Burnell Career Development/Assoc. Professor of Music, MIT
Fellow, Radcliffe Institute                      +1 (413) 575-6024
cuth...@mit.edu                           http://www.trecento.com





--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 
<Vexflow-Three-Voices.png>

Mohit Muthanna

unread,
Feb 5, 2013, 12:56:25 PM2/5/13
to vex...@googlegroups.com
On Tue, Feb 5, 2013 at 11:35 AM, LarryKu <Lar...@hotmail.com> wrote:
In Dan Ringwalt MusciXML post the topic of three voices per stave came up. Rather than hi-jack that post, I decided to start a new one. Last night I decided to test vexflow to see what would happen if three voices were added to a stave. I was quite surprised at the results. In the sample below, I tried to duplicate two of the most common occurrences that I have run into.  The only change to vexflow source was to comment out the 2 voice check in modifiercontext.js.

#1: Notes need to be offset to avoid collision between the voices, and stems from one voice drawing into a second voice (beat 1). The middle voice stem on beat 1 extends too far and overlaps the lower voice. There needs to be a way to shorten stems when needed.

Yeah, shortening stems is tricky right now. In retrospect, having a single StaveNote class that renders the entire note is way too messy. I would rather have separate classes: NoteHead, NoteStem, NoteFlag, etc. and configure them inside a StaveNote (which would just be a container). This would also allow you to have a single note that spans multiple staves.

All this is possible with the current design, but as you can see the code inside StaveNote is getting really complex.
 
#2: Middle voice counter melody with note in between notes of another voice that must be offset (beats 1 & 3).  As you can see the notes in the middle voice were offset when needed. I wasn't expecting that, but it happened.There probably should be a bit more offset of the stems to get some separation. Also, the dot placement is not correct.

I think this part is not that hard to fix.
 
There are more cases, but these are the two most frequent. Overall, implementing three voice capability shouldn't be that difficult.

Agreed, though I think figuring out a nice way to shorten stems might be tricky. One approach would be to do something similar to what Beam does -- delay the stem formatting and rendering until the beam is ready.
 

Comments welcome.

--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Mohit Muthanna [mohit (at) muthanna (uhuh) com]

Mohit Muthanna

unread,
Feb 5, 2013, 1:58:37 PM2/5/13
to vex...@googlegroups.com
On Tue, Feb 5, 2013 at 12:04 PM, Michael Scott Cuthbert <cuth...@mit.edu> wrote:
As far as I know, no music editor correctly imports 3 or more voices per staff without needing human hinting, so the creators of Vexflow shouldn't be hard on themselves if it's not doing it right.  The ideal result in the images currently given (though it doesn't work for everything) would be to have the middle voice use a very short stem so that the beams don't hit the third voice.  It's very hard to do this right in cases where all three voices are close to each other.  One of the notation books (not Behind Bars. Blanking right now) has examples of effective engraving of up to five(!) voices on a staff.

btw -- one thing that might be too late to change now, but has always bothered me a bit in Vexflow: if American English is used for duration types (w, h, q) then the American singular "staff" (where "stave" is almost never used in the singular) would be better than stave.

Yes, agreed. But it's too late to change. (FWIW, I used w, h, q, etc. because I found brieves, quavers, semi-quavers very confusing. :-)

LarryKu

unread,
Feb 5, 2013, 5:50:23 PM2/5/13
to vex...@googlegroups.com, mo...@muthanna.com
Mike - I thought I recognized your name. You are active in the MusicXML forum. Years ago, so was I, but have since lost my forum login information. I still get the forum emails in my Hotmail account.

As I mentioned in my original post, I agree that when possible, shortened stems should be utilized to avoid collisions. In those cases where a stem cannot be shortened to avoid collision, then a person must make a decision whether a third voice should be used at all, but rather combine two voices into one. I also agree with your stave versus staff comment, but for consistency, I use stave in vexflow communications.

Mohit - kudos to vexflow for it's ability to display three voices as well as it does. I was astonished to see the middle voice shift in both tests. I made a quick hack to the stavenote class to enable setting the stem length to something other than 35 to see what shortening stems would do, and it worked great. I agree that trying to shorten stems programmatically would probably be a challenge.

I did modify the tests to see the effect accidentals and fret hand fingers would have on the notation display. They worked like a charm. I moved the modified classes to my server, so you can view the latest tests that includes accidentals, fret hand fingers and shortened stems.

http://el-kay.com/test/vexflow/tests/voicetest.html

BTW: I did verify autobeam works as expected. If a stems direction is specified when applyAndGetBeams is called, the stem directions of all notes are correct. If no stem direction is specified it follows the notation standard stem directions depending on where in the stave the note is positioned.

Mohit Muthanna

unread,
Feb 6, 2013, 11:21:36 AM2/6/13
to vex...@googlegroups.com
On Tue, Feb 5, 2013 at 5:50 PM, LarryKu <Lar...@hotmail.com> wrote:
Mike - I thought I recognized your name. You are active in the MusicXML forum. Years ago, so was I, but have since lost my forum login information. I still get the forum emails in my Hotmail account.

As I mentioned in my original post, I agree that when possible, shortened stems should be utilized to avoid collisions. In those cases where a stem cannot be shortened to avoid collision, then a person must make a decision whether a third voice should be used at all, but rather combine two voices into one. I also agree with your stave versus staff comment, but for consistency, I use stave in vexflow communications.

Mohit - kudos to vexflow for it's ability to display three voices as well as it does. I was astonished to see the middle voice shift in both tests. I made a quick hack to the stavenote class to enable setting the stem length to something other than 35 to see what shortening stems would do, and it worked great. I agree that trying to shorten stems programmatically would probably be a challenge.

I did modify the tests to see the effect accidentals and fret hand fingers would have on the notation display. They worked like a charm. I moved the modified classes to my server, so you can view the latest tests that includes accidentals, fret hand fingers and shortened stems.

http://el-kay.com/test/vexflow/tests/voicetest.html


The shortened stems look great. I'll think of a way to expose shortened stems via VexTab.

The dots look off though, don't you think?
 
BTW: I did verify autobeam works as expected. If a stems direction is specified when applyAndGetBeams is called, the stem directions of all notes are correct. If no stem direction is specified it follows the notation standard stem directions depending on where in the stave the note is positioned.

Great... I added the direction parameter to applyAndGetBeams for VexTab to deal with multi-voice music. The first voice gets the upstems, and the next one gets down stems.

As an aside, I ran some more experiments, and I think we could still do better with automatic rest positioning. Right now your algorithms (which are great) align them with neighboring notes. I think that we could add another formatting pass at the ModifierContext level, perhaps inside formatNotes, to shift rests vertically if they collide with other notes (or rests).

Mohit.
 


--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

LarryKu

unread,
Feb 6, 2013, 2:19:51 PM2/6/13
to vex...@googlegroups.com, mo...@muthanna.com


The shortened stems look great. I'll think of a way to expose shortened stems via VexTab.

The dots look off though, don't you think?

There is a problem with dot positioning in general. For notes on a line, the dot should be positioned in the middle of the space above or below the note depending on other surrounding notes. For instance in the second test, the B on beat 3 should be in the space above rather than on the line. I made a slight change to formatDots to shift the dot when the note is on a line, but it completely messes up the "Basic Dots" test.

In the second example, both dots are positioned too far to the right. The getModifierXY is returning the note head width plus the three pixel spacing I added to offset the stem (extraRightPx) which moves the dot to far to the right. This will take some more investigation, Somehow, if a voice is shifted when it overlaps another voice, the extraRightPx has to be ignored. If you look at the "Multi Voice" rest test, you will see the same extra shift to the right.
 

As an aside, I ran some more experiments, and I think we could still do better with automatic rest positioning. Right now your algorithms (which are great) align them with neighboring notes. I think that we could add another formatting pass at the ModifierContext level, perhaps inside formatNotes, to shift rests vertically if they collide with other notes (or rests).

We never made any changes to modifiercontext to detect rest collisions. This still needs to be done and will most likely be a challenge as the rest heights vary so much. In the meantime, rests have to be manually repositioned with the #number# format in VexTab, or specifying the exact note for the rest (i.e. "G/5") rather than the default "B/4". I think this will work in VexTab.

LarryKu

unread,
Feb 6, 2013, 10:44:25 PM2/6/13
to vex...@googlegroups.com, mo...@muthanna.com
Mohit,

I think I have the dot positioning working correctly. I have no idea how to render the dots on the second and third note groups in the "Dots Basic" test. With all of those notes grouped together, there just isn't any place to render the dots on the displaced notes without overlaying the dots on the normal notes!!  I added the dot tests to the three voice tests so you can see the results.

http://el-kay.com/test/vexflow/tests/voicetest.html

I believe modifiercontext.formatNotes has to be reviewed closely. All of the code is assuming only two notes, and although it seems to work with three voices, I'm not certain it will work in all instances.

Larry

LarryKu

unread,
Feb 7, 2013, 1:47:02 AM2/7/13
to vex...@googlegroups.com, mo...@muthanna.com
Oops, meant to say NOT work in all instances.

Mohit Muthanna

unread,
Feb 7, 2013, 7:51:29 AM2/7/13
to vex...@googlegroups.com
On Wed, Feb 6, 2013 at 10:44 PM, LarryKu <Lar...@hotmail.com> wrote:
Mohit,

I think I have the dot positioning working correctly. I have no idea how to render the dots on the second and third note groups in the "Dots Basic" test. With all of those notes grouped together, there just isn't any place to render the dots on the displaced notes without overlaying the dots on the normal notes!!  I added the dot tests to the three voice tests so you can see the results.

http://el-kay.com/test/vexflow/tests/voicetest.html

That looks excellent! Good point about the displaced notes in the basic test -- I'm not sure where the dots would go either. I'll check "the book" to see if it says anything. (Meanwhile, please send me a pull request for this.)
 
I believe modifiercontext.formatNotes has to be reviewed closely. All of the code is assuming only two notes, and although it seems to work with three voices, I'm not certain it will work in all instances.

Yeah, this is because you can tell apart voice 1 and 2 from the stem direction. I don't think there's any way to tell two voices with the same stem direction apart without tagging the notes somehow.
 

Larry

--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

LarryKu

unread,
Feb 7, 2013, 1:40:53 PM2/7/13
to vex...@googlegroups.com, mo...@muthanna.com
Mohit,

I submitted a pull request to fix the dot positioning. I did add the four note groups shown in the book to the dots basic test.

The pull request also includes changes to stavenote.js to lengthen the beams for 32nd & 64th notes to properly accommodate the extra flags/beams. Currently, the flags extend into the note head.  I had to modify the stavenote_tests to prevent the longer flagged stems from being cut off.

I held off implementing three voices.

Larry

Mohit Muthanna

unread,
Feb 7, 2013, 2:24:13 PM2/7/13
to vex...@googlegroups.com
Thanks -- I'll take a look today.




Larry

--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

LarryKu

unread,
Feb 12, 2013, 7:00:49 PM2/12/13
to vex...@googlegroups.com, mo...@muthanna.com
Mohit,

I have recoded formatNotes for three voices. It shifts voices and shortens stems as needed. It still needs further testing, but you can view the tests at the link below. Test #1 covers different scenarios where notes must be shifted and/or stems shortened. Atlthough I would never write notation this way, I was trying for force various conditions. All of the tests in flow.html are the same.

http://el-kay.com/test/vexflow/tests/voicetest.html
http://el-kay.com/test/vexflow/tests/flow.html


One question, what is the purpose of formatNotesByY? I don't really see any advantage of using this function.

Also, as I have suspected, there is something wrong with the formatter. These tests are justified, and the separation between the eighth notes in test #1 should be the same for each pair. This also occurs in test #2. The eighth note between beats 2 & 3 should be placed midway between the bass quarter notes.

Larry

Mohit Muthanna

unread,
Feb 13, 2013, 9:04:44 AM2/13/13
to vex...@googlegroups.com
On Tue, Feb 12, 2013 at 7:00 PM, LarryKu <Lar...@hotmail.com> wrote:
Mohit,

I have recoded formatNotes for three voices. It shifts voices and shortens stems as needed. It still needs further testing, but you can view the tests at the link below. Test #1 covers different scenarios where notes must be shifted and/or stems shortened. Atlthough I would never write notation this way, I was trying for force various conditions. All of the tests in flow.html are the same.

http://el-kay.com/test/vexflow/tests/voicetest.html
http://el-kay.com/test/vexflow/tests/flow.html

Wow, they look really good. Do you shift/shorten algorithmically, or are manual hints provided? What happens when notes are very close together and have beams?
 
One question, what is the purpose of formatNotesByY? I don't really see any advantage of using this function.

I don't remember -- let me take a look and get back to you. I think it allows you to align multiple note heads that are on the same stave, but I'm not sure.
 
Also, as I have suspected, there is something wrong with the formatter. These tests are justified, and the separation between the eighth notes in test #1 should be the same for each pair. 
This also occurs in test #2. The eighth note between beats 2 & 3 should be placed midway between the bass quarter notes.

This is a corner case that seems to fare poorly with the current formatter. What's happening here is that the displaced note groups (e.g., the three StaveNotes on the first tick in stave 1) consume a larger width quota (the size of two notes). The same thing is happening in tick 6.

The formatter has no visibility into the internals of each tick (by design), just metrics such as 'width', 'extraLeftPx', 'extraRightPx', etc. So I think we can treat the left note as a modifier and increase 'extraLeftPx' by the note width, while decreasing 'width' by the same amount. It's a bit hacky, and I think there may be cleaner ways to fix this (maybe a third formatting pass that redistributes whitespace.)

 


Larry

--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

LarryKu

unread,
Feb 13, 2013, 10:42:09 AM2/13/13
to vex...@googlegroups.com, mo...@muthanna.com

Wow, they look really good. Do you shift/shorten algorithmically, or are manual hints provided? What happens when notes are very close together and have beams?

All shifts/shortens are done algorithmically. There is no manual hinting. I did add a couple functions to stavenote to manually set stem length and force shift of the note group if ever needed, but they aren't used in the tests. I added a third test with a more complex variation of test #1 with 16th notes and voice overlap on beat 1. The second bass "B" eighth note collides with the middle voice beam, but I have no idea how to avoid that. Hopefully no one would ever code notation that looks like that.

 
One question, what is the purpose of formatNotesByY? I don't really see any advantage of using this function.

I don't remember -- let me take a look and get back to you. I think it allows you to align multiple note heads that are on the same stave, but I'm not sure.

It would be nice to know. The function could be re-written, but I honestly don't see a need for it.
 
 
This is a corner case that seems to fare poorly with the current formatter. What's happening here is that the displaced note groups (e.g., the three StaveNotes on the first tick in stave 1) consume a larger width quota (the size of two notes). The same thing is happening in tick 6.

The formatter has no visibility into the internals of each tick (by design), just metrics such as 'width', 'extraLeftPx', 'extraRightPx', etc. So I think we can treat the left note as a modifier and increase 'extraLeftPx' by the note width, while decreasing 'width' by the same amount. It's a bit hacky, and I think there may be cleaner ways to fix this (maybe a third formatting pass that redistributes whitespace.)
 
My first impression without looking at it closely was that the extraRightPx is not being maintained properly. That's what I found in the dots formatting that caused the large separation of the notes in the multi-voice test. Not sure if this is the case or not.


Mohit Muthanna

unread,
Feb 13, 2013, 11:23:03 AM2/13/13
to vex...@googlegroups.com
On Wed, Feb 13, 2013 at 10:42 AM, LarryKu <Lar...@hotmail.com> wrote:

Wow, they look really good. Do you shift/shorten algorithmically, or are manual hints provided? What happens when notes are very close together and have beams?

All shifts/shortens are done algorithmically. There is no manual hinting. I did add a couple functions to stavenote to manually set stem length and force shift of the note group if ever needed, but they aren't used in the tests. I added a third test with a more complex variation of test #1 with 16th notes and voice overlap on beat 1. The second bass "B" eighth note collides with the middle voice beam, but I have no idea how to avoid that. Hopefully no one would ever code notation that looks like that.

Agreed. This is awesome if it's all done algorithmically. I think the only thing left now for fully automatic placement is rest positioning. Very cool!
 

 
One question, what is the purpose of formatNotesByY? I don't really see any advantage of using this function.

I don't remember -- let me take a look and get back to you. I think it allows you to align multiple note heads that are on the same stave, but I'm not sure.

It would be nice to know. The function could be re-written, but I honestly don't see a need for it.

Okay, so looking at this some more it looks like formatNotesByY is more generic and is called when there are more than two voices. If you look at the inner formatting look, you'll notice that formatNotesByY uses relative indices, while formatNotes uses absolute ones. Also, formatNotesByY uses the y-position retrieved from the stave, while formatNotes just infers y-position using note value. Out side of that the algorithms are equivalent.

I think we can just just replace formatNotes with formatNotesByY and everything should work, but I'm not sure if it will break code that wants to format without a stave. (Either way, I think the requirement is probably historical and not worth supporting.)
 
 
 
This is a corner case that seems to fare poorly with the current formatter. What's happening here is that the displaced note groups (e.g., the three StaveNotes on the first tick in stave 1) consume a larger width quota (the size of two notes). The same thing is happening in tick 6.

The formatter has no visibility into the internals of each tick (by design), just metrics such as 'width', 'extraLeftPx', 'extraRightPx', etc. So I think we can treat the left note as a modifier and increase 'extraLeftPx' by the note width, while decreasing 'width' by the same amount. It's a bit hacky, and I think there may be cleaner ways to fix this (maybe a third formatting pass that redistributes whitespace.)
 
My first impression without looking at it closely was that the extraRightPx is not being maintained properly. That's what I found in the dots formatting that caused the large separation of the notes in the multi-voice test. Not sure if this is the case or not.

Right, you can move pixels out of 'width' into either 'extraLeftPx' or 'extraRightPx' -- either will fix this problem.
 



--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

LarryKu

unread,
Feb 13, 2013, 4:38:17 PM2/13/13
to vex...@googlegroups.com, mo...@muthanna.com

I think we can just just replace formatNotes with formatNotesByY and everything should work, but I'm not sure if it will break code that wants to format without a stave. (Either way, I think the requirement is probably historical and not worth supporting.)

All of the current three voice formatting is done in formatNotes. I'm not sure how the formatNotesByY is accessed unless it is called directly.
 
Right, you can move pixels out of 'width' into either 'extraLeftPx' or 'extraRightPx' -- either will fix this problem.

I believe the problem is the notePx metric returned in tickContext. It seems to be doubling the note width in addition to the extraLeftPx and extraRightPx. I just did a quick investigation, and that's what I uncovered.
 

LarryKu

unread,
Feb 13, 2013, 4:53:27 PM2/13/13
to vex...@googlegroups.com, mo...@muthanna.com
Let me clarify my previous post. The metrics returned for beat 1 of Test #1 is:

extraLeftPx 20         Accidental and fingering
extraRightPx 13.5    Displaced note head & extra 3 pixel spacing
notePx 24                Width of normal note head plus the displaced note head. (incorrect ??)
width 57.5                Total of all of the above

I believe notePx should only be the width of the normal note head which would explain what appears to be the doubling effect. I'll try some modifications to see if I can fix the problem.

Mohit Muthanna

unread,
Feb 13, 2013, 4:58:37 PM2/13/13
to vex...@googlegroups.com
Hmmm... yeah, something is weird. Do you mind sending me the metrics for the second and third tick?

 

--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

LarryKu

unread,
Feb 13, 2013, 5:22:27 PM2/13/13
to vex...@googlegroups.com, mo...@muthanna.com
Here are the metrics for the first three ticks and the seventh (the next displaced not head). All of the others are the same as the second.

TICK 1
extraLeftPx 20
extraRightPx 13.5
notePx 24
width 57.5

TICK 2
extraLeftPx 0
extraRightPx 0
notePx 10.5
width 10.5

TICK 3
extraLeftPx 0
extraRightPx 0
notePx 10.5
width 10.5

TICK 7 (first notes on beat 4)
extraLeftPx 0
extraRightPx 13.5
notePx 24
width 37.5

LarryKu

unread,
Feb 13, 2013, 5:34:00 PM2/13/13
to vex...@googlegroups.com, mo...@muthanna.com
I tried commenting out the the notePx in tickContext getMetrics and replacing it with 10.5, and it made a big difference. There was still some additional space between the second half of beat 6 and beat 7, but that may be a the result of the formatter adjusting the tick spacing.

LarryKu

unread,
Feb 14, 2013, 8:22:35 PM2/14/13
to vex...@googlegroups.com, mo...@muthanna.com
Mohit,

I tracked down where the shifted note head width was being doubled. in both the original and new formatNotes functions, the tickable note width was being was being updated, and at the end of the function, the state.right_shift was being updated by the same amount. Two small changes, and the tests have been corrected. I verified all tests on flow.html also. I added the string number tests to the three voice test html as they are some of the more complicated measures. You can see the changes at these links.

http://el-kay.com/test/vexflow/tests/voicetest.html
http://el-kay.com/test/vexflow/tests/flow.html

The changes also helped some of the formatter shortcomings.

Larry

Mohit Muthanna

unread,
Feb 15, 2013, 7:41:49 AM2/15/13
to vex...@googlegroups.com
Wow, very nice! And great sleuthwork on finding the right_shift bug :-)

Please send me a pull request when you're ready, I'd love to merge it.
 

Larry

--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

LarryKu

unread,
Feb 15, 2013, 11:46:33 AM2/15/13
to vex...@googlegroups.com, mo...@muthanna.com
I submitted the pull request. Tthree voices should be plug and play in VexTab if it currently supports more than two voices.

Mohit Muthanna

unread,
Feb 15, 2013, 12:02:23 PM2/15/13
to vex...@googlegroups.com
On Fri, Feb 15, 2013 at 11:46 AM, LarryKu <Lar...@hotmail.com> wrote:
I submitted the pull request. Tthree voices should be plug and play in VexTab if it currently supports more than two voices.

It does, but the stem direction might need to be tailored to your algorithm. Currently, the first voice is "stem up", and the rest stem down, so I guess I need a way to specify stem direction inside VexTab.


--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

LarryKu

unread,
Feb 15, 2013, 1:50:23 PM2/15/13
to vex...@googlegroups.com, mo...@muthanna.com
Actually, you don't have to specify stem directions with multi voices. Some where in vexflow, when there is more than one voice, it automatically sets the upper voice to stems up and the lower voice(s) to stems down. This may not be ideal if someone decides to put the lower voice first, they will get some funny looking notation. I just re-tested it to ensre it would work with no stem-direction specifications.

Dan Ringwalt

unread,
Feb 18, 2013, 3:32:44 PM2/18/13
to vex...@googlegroups.com, mo...@muthanna.com
Everything looks great so far! I'm using formatNotesByY to format notes on two staves together, so I wonder if it's possible to use the same algorithm there. I think it is necessary to use it to justify voices on multiple staves in a part together, but it would be great to also detect when 3 voices overlap on multiple staves.

LarryKu

unread,
Feb 19, 2013, 7:24:30 PM2/19/13
to vex...@googlegroups.com, mo...@muthanna.com

Everything looks great so far! I'm using formatNotesByY to format notes on two staves together, so I wonder if it's possible to use the same algorithm there. I think it is necessary to use it to justify voices on multiple staves in a part

Now I understand the reasoning for the formatNotesByY function, as the current formatNotes only handles one stave at a time. After I get the new formatNotes function completed, rather than trying to duplicate the new formatting code in formatNotesByY, I'll see what can be done to call formatNotes from formatNotesByY to use the new code. It would be much cleaner that way.

LarryKu

unread,
Feb 27, 2013, 4:46:53 PM2/27/13
to vex...@googlegroups.com, mo...@muthanna.com
Mohit,

I am close to getting the three voice formatting with rest collision detection completed. It would have been done a week ago, but I have been ill with the flu and didn't feel good enough to work on the computer. You can view the results at the following links:

http://el-kay.com/test/vexflow/tests/voicetest.html
http://el-kay.com/test/vexflow/tests/flow.html

There are a few tests in flow,html that are broken. I am reasonably certain that it is a function of not sorting the voices in modifiercontext.formatNotes before the new formatting is applied, so the upper voice notes are shifted rather than the lower voice. I will try to come up with a way to sort the voices so we get them in the proper order. You can see how I modified the rest bounding boxes for rests in the Stavenote Bounding Boxes test.

The auto rest positioning tests in the first link shows a before and after comparison. The first test is basically the same as your 'Multiple Playback Instruments" sample in the your "New In My Vexflow" article, I had to move a few notes to create some rest collisions. The second test shows all possible rest combinations for three voices. I tried to add some text above the measures to indicate the first measure shows the default rest positions and the second shows the same notes/rests with the rests shifted. Unfortunately, I couldn't find a way to enter text above the measures that spans several notes without affecting the note spacing. Any idea how to do it?

I am going to create one or more additional tests using 1/8th note and possibly 1/6th note rests to see how they fare with the new formatting.

Another thing I noticed is that not all ledger lines are drawn for rests below the staff. In the second test there are two rests on the "A" ledger line, but the "C" ledger lines are not drawn. This needs to be investigated.


Mohit Muthanna

unread,
Feb 27, 2013, 7:14:25 PM2/27/13
to vex...@googlegroups.com
On Wed, Feb 27, 2013 at 4:46 PM, LarryKu <Lar...@hotmail.com> wrote:
Mohit,

I am close to getting the three voice formatting with rest collision detection completed. It would have been done a week ago, but I have been ill with the flu and didn't feel good enough to work on the computer.

No problem. I hope you're feeling better. The tests look great!
 
You can view the results at the following links:

http://el-kay.com/test/vexflow/tests/voicetest.html
http://el-kay.com/test/vexflow/tests/flow.html

There are a few tests in flow,html that are broken. I am reasonably certain that it is a function of not sorting the voices in modifiercontext.formatNotes before the new formatting is applied, so the upper voice notes are shifted rather than the lower voice. I will try to come up with a way to sort the voices so we get them in the proper order.

Yes, I see the shifted notes. 
 
You can see how I modified the rest bounding boxes for rests in the Stavenote Bounding Boxes test.

Excellent! How did you get the heights?

The auto rest positioning tests in the first link shows a before and after comparison. The first test is basically the same as your 'Multiple Playback Instruments" sample in the your "New In My Vexflow" article, I had to move a few notes to create some rest collisions. The second test shows all possible rest combinations for three voices.

These look excellent! Looking at the 4th tick in "auto adjust rests - three voices", should the bottom rest be slightly lower?
 
I tried to add some text above the measures to indicate the first measure shows the default rest positions and the second shows the same notes/rests with the rests shifted. Unfortunately, I couldn't find a way to enter text above the measures that spans several notes without affecting the note spacing. Any idea how to do it?

If you call .setWidth(0) on the text annotation, the note spacing will not be affected. Alternatively you can use the TextNote class, which gives you more positioning and formatting flexibility.


I am going to create one or more additional tests using 1/8th note and possibly 1/6th note rests to see how they fare with the new formatting.

Another thing I noticed is that not all ledger lines are drawn for rests below the staff. In the second test there are two rests on the "A" ledger line, but the "C" ledger lines are not drawn. This needs to be investigated.

Ouch, I see that. Does this only happen for rests?




--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

LarryKu

unread,
Feb 28, 2013, 8:56:06 AM2/28/13
to vex...@googlegroups.com, mo...@muthanna.com
 
You can see how I modified the rest bounding boxes for rests in the Stavenote Bounding Boxes test.

Excellent! How did you get the heights?

I added upper and lower line bounds to the glyph type properties in tables.js. I was a bit surprised that the rest glyphs are not an even multiple of half-line spacing, so the bounds do extend beyond the actual glyph.
 

These look excellent! Looking at the 4th tick in "auto adjust rests - three voices", should the bottom rest be slightly lower?

When a middle voice stem collides with a lower voice, I chose to shorten the stem at the very beginning of the formatting. Other than at that point, there is no really good point to shorten the stem. It can always be positioned lower by manually specifying the rest position. For instance on the tickable you mentioned, specifying the rest as "G/3" would lower the rest and the shortened stem would be slightly longer.
 

If you call .setWidth(0) on the text annotation, the note spacing will not be affected. Alternatively you can use the TextNote class, which gives you more positioning and formatting flexibility.

I tried using textnotes and that's where I ran into the problem of the text affecting the spacing. Guess I didn't code the textnotes correctly.


I am going to create one or more additional tests using 1/8th note and possibly 1/6th note rests to see how they fare with the new formatting.

Another thing I noticed is that not all ledger lines are drawn for rests below the staff. In the second test there are two rests on the "A" ledger line, but the "C" ledger lines are not drawn. This needs to be investigated.

Ouch, I see that. Does this only happen for rests?
 
The ledger lines are not drawn correctly only for rests, and it is both above and below the staff

Mohit Muthanna

unread,
Feb 28, 2013, 9:10:21 AM2/28/13
to vex...@googlegroups.com
On Thu, Feb 28, 2013 at 8:56 AM, LarryKu <Lar...@hotmail.com> wrote:
 
You can see how I modified the rest bounding boxes for rests in the Stavenote Bounding Boxes test.

Excellent! How did you get the heights?

I added upper and lower line bounds to the glyph type properties in tables.js. I was a bit surprised that the rest glyphs are not an even multiple of half-line spacing, so the bounds do extend beyond the actual glyph.
 

These look excellent! Looking at the 4th tick in "auto adjust rests - three voices", should the bottom rest be slightly lower?

When a middle voice stem collides with a lower voice, I chose to shorten the stem at the very beginning of the formatting. Other than at that point, there is no really good point to shorten the stem. It can always be positioned lower by manually specifying the rest position. For instance on the tickable you mentioned, specifying the rest as "G/3" would lower the rest and the shortened stem would be slightly longer.

Okay, sounds good.
 
 

If you call .setWidth(0) on the text annotation, the note spacing will not be affected. Alternatively you can use the TextNote class, which gives you more positioning and formatting flexibility.

I tried using textnotes and that's where I ran into the problem of the text affecting the spacing. Guess I didn't code the textnotes correctly.

Simply add {smooth: true} to the initialization struct parameter to do this.
 


I am going to create one or more additional tests using 1/8th note and possibly 1/6th note rests to see how they fare with the new formatting.

Another thing I noticed is that not all ledger lines are drawn for rests below the staff. In the second test there are two rests on the "A" ledger line, but the "C" ledger lines are not drawn. This needs to be investigated.

Ouch, I see that. Does this only happen for rests?
 
The ledger lines are not drawn correctly only for rests, and it is both above and below the staff

--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

LarryKu

unread,
Mar 1, 2013, 9:54:00 PM3/1/13
to vex...@googlegroups.com, mo...@muthanna.com
Mohit,

I believe the new formatNotes is working as planned. I'm sure there are probably some bugs, but we will have to address them as they are found. Check out the tests and let me know if you see anything that doesn't look correct.

http://el-kay.com/test/vexflow/tests/voicetest.html
http://el-kay.com/test/vexflow/tests/flow.html

Larry

Mohit Muthanna

unread,
Mar 2, 2013, 10:06:16 AM3/2/13
to vex...@googlegroups.com
Awesome! Please send me the pull request.


--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en
 
---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Reply all
Reply to author
Forward
0 new messages