Incorrect playback of cross-staff trills

• Jul 20, 2015 - 16:31
Reported version
S4 - Minor

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

Attachment Size
trill-playback-cross-staff.mscz 3.75 KB


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.

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());