Change instrument via staff properties doesn't affect clef

• Mar 12, 2010 - 21:21
Reported version
S4 - Minor

Steps to reproduce bug
1. Create score for Violin
2. Right-click on an empty part of the staff, choose Staff Properties
3. Switch to Double Bass
4. Press "OK"

Expected behavior: Staff should now have a bass clef

Actual behavior: Staff still has a treble clef

MuseScore version: r.2878 nightly

(Operating System: Windows 7)


Status (old) patch (code needs review) active

Came up again at #114501: When instrument is changed (via "Change Instrument" in Staff Properties"), initial clef is not changed (as seen in Instruments). Labeling as active again because the PR was closed long ago, and the problem is still the same.

I encountered it today, trying to update the templates after All that should be needed is to open the templates with the updated instruments.xml and use the "Change Instrument" button in Staff Properties. But it changes the transposition without changing the clef. Adding a different clef to the beginning is not a solution, because of #62221: Template with Bass clef converts to Treble Clef when used to create a new score.

, If I'm understanding correctly, though, the updated template will work if the user who creates a score from that templater *also* has the updated instruments.xml, though. Right?

I don't think so? I thought in general everything is in the MSCX code, regardless of instruments.xml—like even if you have no instruments.xml at all you can still open scores and they'll be just the same.

That could be, but if so, then what you are describing should work. I mean, clearly templates involving bass clef instruments *do* work correctly in general. The issue you referenced is marked "needs info" because it seems to involve some sort of unknown use case. If you think you have steps to reproduce an actual issue, maybe you could could clarify there.

EDIT: Hmm, maybe I guess you mean you have a template that was originally created with one instruments/xml file but then you edited the instruments.xml and then tried to reuse the same template and somehow force it to see changes in the modified instruments.xml? That indeed isn't likely to work. Youd need to hand-edit the template I guess.

I have a feeling we may be talking about entirely different things, but if you're asking how to reproduce #62221: Template with Bass clef converts to Treble Clef when used to create a new score, it couldn't be simpler. [Note that instruments.xml does not enter into it.]

1. Create a score for tuba.
2. Right-click, Staff Properties, Change Instrument... to violin. Click OK.
3. Initial clef isn't treble clef (this issue), so drag treble clef from Clefs palette onto first measure, or double-click it directly onto the initial clef.
4. Save file to templates folder, restart MuseScore.
5. Create new score from that template. It's got a bass clef, like the tuba, even though it's a violin.

The original report said nothing about change instrument - he described a score for flute and bassoon period. It was just a guess on my part that an instrument change *might* have been the cause. We never got confirmation on that. It does still seem a good guess though.

I'm going to give a try at fixing this, and been skimming these related issue reports. The resistance from marc (maybe some others?) seems to be summarized by :

when you change instruments, MuseScore changes the name of the staff, the playback sound, and the transposition of the notes but leaves everything else. If you want to change clefs, or change octave of the notes, or make any other changes besides name, transposition, and sound, you need to do it yourself. MuseScore has no way of know what other changes you'd want made.

While I agree with not changing octaves, I do consider a clef change to be an essential component of an instrument change. So just like instrument change already changes the name of the staff, the playback sound, and the transposition, I would argue that the user has told musescore to change the clef if necessary by the user's act of changing the instrument.

I will have musescore generate a clef at the instrument change if the new instrument's default clef is different from the most prior clef in that staff, as well as to have all future generated clefs reflect the new instrument's default clef up until another change instrument or manual clef occurs.

I will add a checkbox to selectinstr.ui which will be checked by default that says: "Change clef to new instrument's default". Then the user can manually disable the automatic clef change if for some reason does not want to.

For the record, I have nothing against changing the behavior. My comment quoted anovenwas just explaining how thinhs are. Adding clef to the list of attributes we change is fine, the only real complication is how to handle clef changes within the score.

There is no need to change the actual clef, but change the default clef, so that when you delete the actual clef, the instrument's default clef shows. So it is a matter of changing the instrument definition in the score to that of the changed one completely

After looking through the code, I've come to the conclusion that adding a checkbox "Change clef to new instrument's default" makes implementation much more complicated, in particular figuring out undo, as well easier things like the fact it would require an addition to the .mscx format.

Jojo, I got the default clef to be updated for system headers, by modifying Staff::clefType(int tick)
like so:…

But the problem I'm still trying to figure out how to properly create a generated clef at the tick of the instrument change...this is the function that I'm generating the clefs with...I can step through that function and reach the part where I've added the segment with the generated clef, however I need to figure out why it isn't displaying yet:…

I'll have to take a look with a fresh mind tomorrow, but if you want to take a quick peak at that and let me know if I'm way off base, that would be nice at least.

Todo: the clef will only be generated at the tick of the instrument change if the new instrument's default clef is different from the currently existing one.

Hmm, I didn't think anyone was talking about changing what happens in a mid-score instrument change (or, Instrument text). This issue is about the Change Instrument command issued globally for a staff via Staff Properties. This, only the initial clef at tick 0 and the default clef insrted if you end up inserting new measures, or deleting that initial clef, etc.

Oh my gosh, I can't believe I completely misread that. Well seems original issue is much simpler. Although I ought to file a seoerate feature request for what I was starting on.

I agree the initial request was about changing the instrument on a staff rather than a mid staff change, but I believe the mid staff change should work the same which ever way it is implemented. I have previously said the clef change was unnecessary, but the more I think about it the more I think the clef change, if needed, is the better option.

What's confusing is that there are actually three separate issues being discussed here.

1) The original issue: what happens to the clefs actually present in the score if you do Staff Properties / Change Instrument. The consensus was, change the *initial* clef on the staff to whatever the default clef is for the new instrument, leave the other clefs alone. This was never actually implemented. But it's easily worked around - simply change the clef manually.

2) A related but separate issue: what should happen to the *default* clef. That is, assuming you change the initial clef manually, what happens if you then delete it, insert new measures at the beginning of the score, etc. I think there is also consensus that the default clef for the new instrument should win. I figure we might as well keep these two issues connected.

3) Unrelated issue: what happens when doing a Change Instrument mid-score, using the Instrument Change element. This deserves a separate issue. This to me is less clear about I would imagine it's pretty rare to ask a musician to change to an instrument that reads a different clef than his usual instrument, and indeed, when this does happen, it might not be unusual for him to want to read it in his native clef but apply octave transposition as necessary (eg, a trumpet player asked to switch to baritone horn for some given passage). Anyhow, between how rare this case probably is an d how unclear it is what the desired behavior might be, I really don't care one way or the other what we do by default as long as it possible to override it. Right now we default to no clef change, but I can add one manually if I like. If we default to changing clef, it better be possible to remove it.

Title Change instrument doesn't affect clef Change instrument via staff properties doesn't affect clef

Regarding (3), after I spent some time trying to figure out how to generate a clef only if necessary and only if user had selected a chexbox in changeinstr.ui for mid-score Instrument Change text, I've come to the conclusion that implementation is non-trivial, so I'm thinking probably not worth it, even though I wanted such a feature and even though I wasted a bit of time trying to.

Regarding (2), that is a much more trivial fix: simply change the default clef, and then all generated clefs will be updated. I support this.

Regarding (1), I disagree with such a feature as I don't see the point of putting extra effort to handle the initial clef specially, since is much easier to just change the default clef with (2). Anyway user might have already manually dropped an initial clef, but I think manually dropped clefs should not be updated by any staff instrument change.

I changed the title so everyone knows this issue is unambiguously not referring to change instrument text.

I think I have a fix:…

Note the following corner case when changing a staff starting with a grand staff instrument (like piano):
A) If change the top (treble) staff into a treble-clef instrument (such as pretty much any woodwind), then the top staff remains as treble and the bottom staff remains as bass.
B) If change the bottom (bass) staff into a bass-clef instrument, then the bottom staff bass clef remains.
C) If change the top (treble) staff in to a bass-clef instrument, then the top staff changes to bass clef, so now have two bass clef staffs.
D) If change the bottom (bass) staff into a treble-clef instrument, then the bottom staff changes to treble clef, so now have two treble clefs staffs.

This makes perfect sense to me, and results exactly from this line in editstaff.cpp :

ClefTypeList clefType = instrument.clefType(orgStaff->rstaff());

Let me know if anyone is upset by that.

Now I should warn that since the staff change only operates for that *specific* staff being changed, that therefore if started with the case (D) with two treble clefs, if user then right clicked on the top staff and changed its instrument to "Piano" via staff properties, that the result would still be two treble staffs. This makes perfect sense to me, since the user had only specifically clicked on the top staff, and since ChangeStaffType only operates on a specific staff. But if anyone is upset by this, please suggest an alternative, although to me this makes sense (and keep in mind that such an operation changing between grand staff instruments and single-staff instruments is an unusual use case anyway).

And I'm also noting that my fix here only applies to the staff's *default* clef. So that means that had the user manually dropped any other clef anyway (including as initial), then whatever clef the user dropped would remain, but only *generated* clefs would be affected by the staff instrument change.

Does changing the default clef change the initial clef if the user had *not* manually changed it? I would have thought not, but if so, great, that does what I think most people would want for #1.

Note: If user had already created parts via File->Parts, and if the user then changes a staff in a child score or in the parent score, then be aware that my commit by itself does not change any linked staffs. This is because changing instruments via staff properties currently only appears to perform the staff change for the particular score & staff being edited (without propagating that staff change to linked scores).

I'm also noting for the record, that apparently changing the instrument will change the sound and transposition for all staffs in that score for that part (including linked staffs in that same Score object but not other Score objects). However, the default clef change only applies to the staff that the user had right clicked. As I mentioned before, that is a direct result of the fact that I've made the clef type change to be part of the ChangeStaff operation :

score->undo(new ChangeStaff(orgStaff, inv, clefType, userDist * score->spatium(), nhide, ifEmpty, hideSystemBL));

The fact that staff properties changes don't propagate to linked parts is an issue to be sure - specifically, it's #62416: Changes to staff transposition (and other properties) not reflected in linked parts. Fixing this does not appear to actually be *hard*, but there are some cases to consider where the correct behavior is non-obvious (like, linked staves in the same score, attempts to use the discrepancy as a way to automatically get concert and various transposed parts in one step, using the discrepancy as a way of implementing capo / tablature, perhaps other possibilities I am not thinking of right now.

Status (old) active patch (code needs review)

I wasn't able to create a libmscore mtest, because this operation sortof depends on the Edit Staff GUI (not just libmscore...I'd eventually like a way to test GUI operations). But I've personally tested a bit and haven't noticed anything unusual. Here is PR for 2.1:

Seems fairly "safe" and straightforward.

Status (old) patch (code needs review) fixed

Fixed in branch 2.2, commit 604161ef65

fix #4954 Change staff instrument changes default clef

Right-clicking a staff and changing the instrument in editstaff.ui will now also change the default clef for that staff based upon instrument.clefType(orgStaff->rstaff()) such that any generated clefs (including the staff's initial clef if user did not manually drop another initial clef) will obey the new instrument's default clef for that staff.