Incorrect playback of cross-staff trills
Ubuntu 14.04, GIT commit: 1a5875b
1) load attached file, showing trilled notes moved from one staff to another via shift+ctrl+up/down
2) play
Result: the trills on the cross staff notes have notes from the wrong octave.
Originally reported in https://musescore.org/en/node/69676
Attachment | Size |
---|---|
trill-playback-cross-staff.mscz | 3.75 KB |
Comments
My little analysis:
One problem is in function convertLine in rendermidi.cpp
This function relies on chord->staff() returning the staff a note is actually shown, which is not true for a cross staff note. Therefore the line for a cross staff note is calculated using the wrong clef (of the original staff instead of the staff the note is shown).
Second, in function articulationExcursion a clef check for the first note would also be needed if it's a cross staff note.
I'm trying to fix it, but experiencing some problems fully understanding what's going on here, so I did not yet succeed.
The part of
rendermidi.cpp
dealing with ornaments and articulation is not very obvious indeed.I am rewriting some part of it, also adding comments, to make it a little bit more consistent, but without so far any change in the logic (to avoid regressions) as part of this pull request dealing with #23063: No way of controlling gateTime at present in nightlies. Maybe it is the case to coordinate changes to it?
I found out that the same problem exists if you add a 8va line to it. Should this be created as another bug report?
Wouldn't hurt. Perhaps they'll both be fixed together, but it would almost certainly different code required.
This is really a funny bug. The note appears in a different staff than its note->staff() property indicates.
If I enter a note in the bass clef of a two staff system, then press Shift-Cmd-Up, it "apparently"
moves up to the treble clef staff. But It appears that chord->staff() is still the bass clef.
So a chord has a chord->staff() and a note has a note->line() but the line.
Can someone explain the relation of staff() and line() in the cause the user has pressed Shift-Cmd->Up or Down? One clue is that note->line() returns -1000 which is Ms::INVALID_LINE. It also seems when I press Shift-Cmd->Up the entire core (not just the note) jumps to the other staff. So my guess is that the clue is in the Chord class not in the Note class.
For the calculation done by the trill (and all articulation) calculation I need to know the line in the same staff. So I'm happy to have the line and the staff the note is sitting in graphically, or I'm happy to have the other staff and the line as if the note was on a ledger line. How can I get one or the other of these?
The trick seems to be to use the staffMove() method.
// we canot use staffL = chord->staff() because that won't correspond to the noteL->line()
// in the case the user has pressed Shift-Cmd->Up or Shift-Cmd-Down.
// Therefore we have to take staffMove() into account according to the following formula.
Staff * staffL = noteL->score()->staff(chordL->staff()->idx() + noteL->chord()->staffMove());
I've added a more extensive comment to articulationExcursion. It should be easier the next time someone tries to look at it. To see the comment, take a look at PR https://github.com/musescore/MuseScore/pull/2759
I'm adding trill-playback-cross-staff.mscz as a test case. The test case name is testTrillCrossStaff in test_midi
Fixed in branch master, commit 4af2bbe41c
fix #70016: fixed formula to calculate staff given a note in presence of staffMove
and added test case testTrillCrossStaff
Fixed in branch master, commit 30c0d4b602
Merge pull request #2759 from jimka2001/70016-cross-staff-trills
Fix #70016: cross staff trills
Fixed in branch 2.0.4, commit b0a18e79c8
fix #70016: fixed formula to calculate staff given a note in presence of staffMove
and added test case testTrillCrossStaff
Automatically closed -- issue fixed for 2 weeks with no activity.