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

Non-power of 2 tuplet isn't the best choice for durations like 5/6 QL #572

Open
jacobtylerwalls opened this issue Jul 5, 2020 · 4 comments · May be fixed by #1240
Open

Non-power of 2 tuplet isn't the best choice for durations like 5/6 QL #572

jacobtylerwalls opened this issue Jul 5, 2020 · 4 comments · May be fixed by #1240

Comments

@jacobtylerwalls
Copy link
Member

jacobtylerwalls commented Jul 5, 2020

Found while running stripTies on Schoenberg op19/6, measure 8, but minimal example here:

eighth = note.Note(quarterLength=0.5)
tripletEighth = note.Note(quarterLength=(1/3))
eighth.tie = tie.Tie(type="start")
tripletEighth.tie = tie.Tie(type="stop")

s = stream.Stream()
s.append((eighth, tripletEighth))
s.makeMeasures(inPlace=True)
s.stripTies(inPlace=True)

singleNote = s.flat.notes[0]
(singleNote.quarterLength, singleNote.duration.type, singleNote.duration.tuplets[0])
(Fraction(5, 6), 'quarter', <music21.duration.Tuplet 6/5/32nd>)

Math checks out, but neither a musicxml export nor a roundtrip back using makeTies will do anything with the 6-in-the-space-of-5 32nds tuplet, which makes for difficult to read output (or lost information if the musicxml importer decides to drop the tuplet bracket on the note altogether).

I'm suggesting quarterConversion could try harder to come up with a complex type. In this instance it would involve storing five components of 16th notes, then a 3/2/16th tuplet applied to the whole thing. m21ToXml splits on components when exporting, so I would expect a clean export if we had a complex type. makeTies could also do something similar to ensure a roundtrip after stripTies came back the same.

I looked at how the duration algorithm works now, and for an input of 5/6 QL it finds 1/2 QL first, then looks at the remainder (1/3 QL) to see if it could be added as a second component, but by design does not allow tuplets. But we could find the LCM and make sure's it under an acceptable ceiling.

@mscuthbert
Copy link
Member

Lemme think through this a tiny bit more -- You're probably right. Do Finale/Sibelius/etc. also have a problem if the rest of the tuplet is present? The other 1/6 note?

@jacobtylerwalls
Copy link
Member Author

It's a little worse with the other 1/6 note, on account of the way music21 closes the tuplet bracket.

Just a 5/6 QL note:
Screen Shot 2020-07-14 at 6 17 02 PM

A 5/6 QL note and a 1/6 QL note:
Screen Shot 2020-07-14 at 6 17 37 PM

In the first case, the Finale import is reasonable, since music21 generates <tuplet bracket="no" ...
Not clear to a reader, but reasonable given the bizarre tuplet defined.

In the second case, the Finale import is probably hindered when music21 extends the existing tuplet bracket (5/6/32nd) and closes it on the second note, even though that tuplet is different (3/2/16th):

      <note>
        <pitch>
          <step>C</step>
          <octave>4</octave>
        </pitch>
        <duration>8400</duration>
        <type>quarter</type>
        <time-modification>
          <actual-notes>6</actual-notes>
          <normal-notes>5</normal-notes>
          <normal-type>32nd</normal-type>
        </time-modification>
        <notations>
          <tuplet bracket="yes" number="1" placement="above" type="start">
            <tuplet-actual>
              <tuplet-number>6</tuplet-number>
              <tuplet-type>32nd</tuplet-type>
            </tuplet-actual>
            <tuplet-normal>
              <tuplet-number>5</tuplet-number>
              <tuplet-type>32nd</tuplet-type>
            </tuplet-normal>
          </tuplet>
        </notations>
      </note>
      <note>
        <pitch>
          <step>C</step>
          <octave>4</octave>
        </pitch>
        <duration>1680</duration>
        <type>16th</type>
        <time-modification>
          <actual-notes>3</actual-notes>
          <normal-notes>2</normal-notes>
          <normal-type>16th</normal-type>
        </time-modification>
        <notations>
          <tuplet number="1" type="stop" />
        </notations>
      </note>

Finale probably realizes that the tuplet brackets shouldn't actually continue since the <time-modification> elements differ. Sibelius also has trouble. The squiggle by the cursor is some sort of distended bracket:
Screen Shot 2020-07-14 at 6 41 22 PM

I haven't isolated the set of rhythms that will cause Finale to discard the entire bracket, as in the Schoenberg.

Likely output if we find a complex type (and without adding logic in TupletFixer trying to get back to 1/2 + 1/3):
Screen Shot 2020-07-14 at 6 32 14 PM

That seems like an improvement over the status quo even without restoring 1/2 + 1/3.

Not intending to work on this just yet -- speedy reply not expected!

@mscuthbert
Copy link
Member

Thanks! You've definitely demonstrated that this is a bug -- and a regression from v. 5 -- so we'll try to not dynamically create tuplets that don't have denominators that are either 3 or a power of two. That will fix this problem.

@jacobtylerwalls jacobtylerwalls changed the title Enhancement: Find a complex type for some non-power of 2 tuplets Non-power of 2 tuplet isn't the best choice for durations like 5/6 QL Nov 15, 2020
@jacobtylerwalls
Copy link
Member Author

See more discussion at #1237

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants