Inconsistent octave selection in note input mode

• Nov 3, 2018 - 20:27
Reported version
3.0
Priority
P2 - Medium
Type
Ergonomical (UX)
Frequency
Once
Severity
S4 - Minor
Reproducibility
Always
Status
closed
Regression
No
Workaround
No
Project

Notes are supposed to be entered into the nearest octave to the last note. Currently several of the note combinations are wrong, while others are correct. In this picture

note octaves.PNG

you can see the bass clef notes that are entered by default in the key of E-flat. In the key of C, the results are as expected

note octaves 2.PNG

The key should not affect this since it's 6 half steps up from A-flat to D-flat and 7 half steps down. It is the exact same distance from A to D and from E-flat to A-flat in both directions.

It seems this also happened in previous versions but I wasn't able to determine when it selected the wrong octave.


Comments

I remember looking at this some time ago. The issue as I recall was that the way note input works, at moment you press a letter key, we haven't calculated yet whether it might be flat or sharp (due to the key signature or an earlier accidental), so we are actually always calculating relative to the plain "white key" note. So potentially (probably about half the time) wrong results are obtained if the about-to-be-entered note is a "black key". Something very much like that anyhow. I think I may have tried out some sort of hacky heuristic to improve the odds of success, but my memory is very fuzzy here.

In reply to by Marc Sabatella

I have a fuzzy memory of discussing this once before as I stated. If the current key signature were taken into consideration then the future application of an accidental becomes irrelevant. The key signature isn't even ignored or both the key of C example and E-flat example would have the same results.

I don't know what kind of complicated logic is leading to making the wrong decision, but it should be a simple case of is place the note in the current octave less than 7 half step? If so, then just enter the note. If it's more than 7 then move the note to the farthest adjacent octave to the note. So if you enter a C5 then an F, F is more than 7 half steps from C, since F is higher than C, move the F to the octave in the opposite direction which is down to enter an F4. Since it probably uses the midi pitch number then enter the F that is pitch of the F in the same octave minus 13, to find the proper pitch number.

This logic is slightly simplified because there has to be a conversion from midi pitch to octave number and back to midi pitch, but that can't be too big of a deal.

My recollection is that the key signature is ignored when it comes to guessing what the pitch of the note about to be entered is. The previous note has already been entered, so no guessing involved, and the key signature has already been taken into account.

So for instance, key of C, you've entered a B and then you type E. MuseScore knows the B is a B natural. When you type "E", as I mentioned, currently MuseScore does not attempt to guess whether that will result in a E or Eb or even E# - the answer depends not only on the key but also which octave it ends up choosing and whether there is an accidental on that note in that octave earlier in the measure. So it just guesses E natural, and calculates that the E natural above the existing B is closer, so it picks that, enters the E, and this does indeed turn out to be an E natural, so this turns out to be a good decision.

On the other hand, in key of Eb, MuseScore still makes no attempt to guess whether typing E will result in a E natural, Eb, or E# - again, the answer depends not only on the key but also on which octave it ends up choosing. So it just gives up and guesses E, which is silly because it would be better to guess Eb to at least be consistent with the key, but that's what it does. It then calculates that E natural is the same distance from Bb whether you go up or down, so it's a coin toss, and in this case, down wins, and it tries to add the E below the Bb. At this point, it finally discovers that adding an E on that line yields Eb (in this case because of the key), so picking down turns out to have been a bad idea.

The simple but not totally correct improvement would be to at least consider the key when guessing what note would be added when you type "E". Then we'd know ahead of time that typing "E" would probably yield Eb when in the ley of Eb, and we'd correctly choose to add it above the Bb.

So it's a bit of a chicken and egg problem - until we know which octave wins, we don't know for sure what accidental would be applied, which throws off the distance calculation, causing us to pick the wrong octave sometimes. But if we at least took the key into account, we'd guess wrong a lot less often. Then it would only be accidentals earlier in the measure that would cause us to sometimes guess wrong.

In reply to by Marc Sabatella

I believe taking the key signature into account would be preferable since, as you said, it would be correct in choosing the closer note more often. I don't mind the coin toss always deciding on down, it's better than a random coin toss. Getting a consistent result makes it easier to know if I'll need to use ctrl+arrow immediately upon entering a note to move it to the correct octave.

Severity S4 - Minor S3 - Major

In this video, I selected the rest, pressed E (on the alto clef) then D. Notice the octave jump because it crossed the bar line. This doesn't happen if there is no bar line and clef has no effect.

octave jump.gif

Since this is part of the same algorithm I'm putting this in the same bug report so maybe they will both be fixed at the same time.

That case looks like a true bug, not just an inherent chicken-and-egg limitation in the algorithm. But I can't reproduce. I tried creating a score with alto clef, four sharps, entered E then D across a barline as you did, but got the expected result. So here we'll need the score itself.

In general, videos are nice, but sample scores are still a good idea if it's anything more than a single measure that is obvious how to enter from scratch.

This has happened consistently in this score and other places. I actually found the issue on the Cello staff, then tested it on the viola staff. I'm very aware that pictures aren't always the best way, but I didn't think it was score specific, especially since it was seen on multiple staves and I've noticed it before. If I can reproduce the problem I'll post steps. Until then...mysteries in the deep.

It was mentioned that the nearest-note logic should account for the key signature, but why should this matter? Shouldn't it just be based on the number of lines & spaces a note would jump (e.g., avoid jumps larger than a fourth)? Anyway, here's the result of typing "EBEBEBEB" in note entry in the key of C major vs. E-flat major:
MS3_nearest_note.png
I'm not sure why key signature should be affecting the logic here since the interval is identical between E-B and Eb-Bb.

The issue with key is, until we actually add the note, we don't knownthe exact pitch. We need to look at the key as well as earlier accidentals in the measure to known the pitch you'll actually get when you type a letter. So it's a chicken and egg question. Does that make sense? I can try to explain in more detail if not.

Btw, I see what S. Christian is saying, instead of trying to pick the closest note chromatically, we could just count lines and spaces. This would just change the specifics of which cases we get wrong, though, if one is expecting a true "closest" note.

In reply to by mike320

As I understand it, MuseScore will try to add the entered note at the nearest interval to the preceding pitch, correct? This means the largest interval jump should be a fourth. Accidentals have no bearing on what is considered a fourth--interval is determined entirely by the note letter names. A up to D is always a fourth on the staff, and accidentals only determine the quality, e.g. perfect, augmented or diminished. The distance in lines & spaces will always be the same. Unless I am misunderstanding something, I don't understand why accidentals should have any bearing on MuseScore's nearest-note logic.

The algorithm is chromatic - in other words, based on number of semitones. That is why both key signature and accidental status are relevant but unfortunately are ignored currently.

Maybe it would be better if we switched to "dumb" algorithm based on lines and spaces only?

In reply to by s.chriscollins

Marc, in what scenario would a note be chromatically closer when added in one direction while actually creating a larger note-name interval? As far as I know, the only way to achieve this would be a double-sharped fourth or double-flatted fifth, but I can't imagine any scenarios where this would be the correct spelling. Nor can I imagine a user being unforgiving when his double-flatted interval wasn't the one chosen by the note entry logic.

The obvious case to me is a score in E that has a Db (due to an accidental) and then you type G - or any transposed variation. So sure, a doubly-diminished fifth, and not worth worry about.

I'm fine with someone re-implementing the algorithm to work that way, it would solve the key signature issue and only break cases no one likely cares about.

In reply to by Marc Sabatella

Since an heuristic can only go so far, it would be nice to be able to explicitly control the direction without moving back to the note. I.e., have prefix keys meaning "up/down relative to the previous note", or commands meaning "move the previous note up/down an octave" (which would allow adjustment without going back to the previous note during note entry), or modifier combinations (shift, control, etc) to specify the direction during note entry. I'm a new user, so I imagine there is an answer for this, or else it has been discussed before. Apologies if this is a dumb comment.

First of all one needs to define what one means by "closest", since there are two possible systems: closest in absolute pitch, or closest in the scale/tone system. In terms of absolute pitch, C#'-->Gb' is the same interval as Db'-->F#', five semitones, and the second of the notes should therefore be placed in the higher octave. But from a musical point of view, the first interval is a fifth (albeit a double-diminished one), and the second a third, so in the first case it should go down, in the second up.
There are several reasons why I consider the second alternative the better. The first is the more principled one: I have to teach my theory students all the time that Eb and D# are two different - VERY different - tones even though they share the same key on the piano. Any tool that is based on the musical logic behind the notation system would have an advantage over those that don't.
The second reason is that we do not enter pitches, we enter notes, scale steps - we don't enter 493Hz, we enter a B, a Cb, an A double-sharp, etc. There really should be no reason to have to guess: the input key plus whatever modifications are in operation (key signature, accidentals) is all one needs to know. This also accounts for tritones, where the distance up and down is the same. In the pitch system, this will be ambiguous - in the scale system not.
The third reason is the simplicity and consistency of the calculations. No need to guess, no room for ambiguity. I once worked out an input system for Lilypond in vim, which might be useful here as well. I am by no means a programmer, but I made it work, which, given the quirkyness both of vim and of Lilypond, I take as a sign of success. My approach was:
- Initialize an array/dictionary which maps keyboard keys to scale steps. The initial value could be cdefgab or be taken from the key signature.
- Determine which keys are meant to enter notes and which to modify the map within the possible values, from double-b to double-# (e.g. change a[key]=A[note] to a=A#)
- If "enter note" then pass on the mapped value, if "modify", then store the new array (so that the next a will also be entered as A#).
I haven't had a look at how Musescore handles this. If someone could point me to the place in the code where this is done, I'd be interested.

The algorithm counts semitones now, but as I've mentioned, it is often wrong in borderline cases because it does not actually know what pitch you are about the enter until it is actually entered. That is, when you type "D", don't actually know if it's going to be D natural, flat, or sharp, until it's already entered. And indeed, the answer may well depend on the octave:

chromatic-2.png

Ideally, yes, if you type "D" while on beat 4, the algorithm would say, "now, if I put this in the higher octave, it would be a D#, and that means it is 8 semitones away, but if I put it in the lower octave it would be a Db and thus is 6 semitones away, I should pick the lower octave". I guess. I can't say I care that much, I rather like the suggestion that we give up on counting semitones and just count staff lines, even though that means we'd pick the upper octave in this case.

Attachment Size
chromatic-2.png 9.11 KB

Which indeed is the right place, musically speaking, since it's only a fourth up. In addition to there being no borderline cases, there is also the additional advantage that changing e.g. from Db to D# would not put it in the "wrong" octave, since any D is a D, thus some kind of fourth above any A.
It may not be a matter that many people care about, but (a) a system that creates ambiguity and wrong solutions in one place, may do so in other places as well, and (b) I do much of my work touch-typing in scores, often without headphones, and then it is really important to be able to rely on the consistency of the system. It is no fun to discover after ten bars that one is two octaves too low.

Status active PR created

eyolf, you make a very clear and convincing case. Key signature should be ignored, as well as any accidental on the previously entered note. Fortunately this is very easily accomplished within the context of the current algorithm, since it already works perfectly in the key of C when the previous note has no accidental. The algorithm simply needs to calculate the octave for the next note based on what the previous pitch would have been if it were unmodified by accidental and/or key signature. See https://github.com/musescore/MuseScore/pull/6052.

In reply to by mattmcclinch

Thank you - this looks very promising. I am looking forward to trying it out.
On a related note (which should perhaps be a separate issue): it would be consistent with this approach to let redefine the keys for accidentals to not simply prefix a # or a b, but to ADD a # or a b to the current accidental, so that e.g. pressing the "flat" key on a C## would change the note in the sequence C## -> C# -> C -> Cb -> Cbb, rather than simply changing it to Cb directly.

"On a related note (which should perhaps be a separate issue): it would be consistent with this approach to let redefine the keys for accidentals to not simply prefix a # or a b, but to ADD a # or a b to the current accidental, so that e.g. pressing the "flat" key on a C## would change the note in the sequence C## -> C# -> C -> Cb -> Cbb, rather than simply changing it to Cb directly."

The only part of this comment that I agree with is the part that I have highlighted in bold.

In reply to by frfancha

I will post it as a separate issue, but I'd like to answer here as well:
No, not exactly. There are two main differences:
- the up and down arrows do move the note up/down a semitone, but with no regard for the key, only direction, so in order to turn an f into a gb, you have to go up two and down one. That's in itself fine, but it's inconsistent, since you will not get an f flat going down from f.
- More importantly: as far as I remember from a previous discussion, the up/down arrows can not be remapped to other keys, which means that if one uses some kind of touch-typing system for entering music, one has to move constantly back and forth to the arrow keys.
- And lastly: The arrow keys don't add or subtract within the stack of accidentals (double-flat - flat - natural - sharp - double-sharp), but changes the TONE and assumes the most likely note sign for the new pitch. There is no way to enter a double-sharp with the arrow-keys, unless there is already a sharp in the key signature.

In reply to by eyolf

@eyolf Yes I know all that thanks, but I was specifically answering to the question of being able to do this:
C## -> C# -> C -> Cb -> Cbb
with one key stroke by step only.
And it seems to me that this part:
C## -> C# -> C
is easily done with down arrow (down arrow from C## gives C# even when D is flat in the key signature)
C -> Cb requires you assign a shortcut to action "Note input flat" (except if your B is flat from key signature)
and Cb -> Cbb requires you assign a shortcut to action "Note input double flat"

So once a shortcut is assigned to "Note input flat", and we have C#, the question that was asked is to be able to do
C# -> C -> Cb
with that shortcut, while today using it will directly do:
C# -> Cb
As we already have down arrow to do C# -> C, I'm not sure that is a good idea that a second shortcut would achieve the same thing and remove the possibility to do directly C# -> Cb

In reply to by eyolf

For the record, yes you can customize up/down in this context, probably not for manual adjustments in edit mode.

And the rule is actually consistent once you know it: use raised scale degrees (sharp or natural) on up, lowered (flat or natural) on down, but always prefer diatonic spelling. So in the key of C, G then up yields G#, but up again yields A not Gx because A is diatonic. That’s the same reason B then up yields C not B#.

In reply to by Marc Sabatella

I don't mind so much the way up/down arrows work: as you say, it's consistent and not hard to understand. What I do mind is (a) that it can't be mapped in edit mode (which is where I work most of the time) and (b) the underlying pitch-based system, instead of a consistent diatonic, scale-step based system.

I think you are misunderstanding what edit mode is. It's normal mode that you spend most of your time in. Edit mode is what happens when you double-click an element in order to show its handles and make fine positioning adjustments. You'd be there only for a few moments at a time, and that's the only place you can't redefine the behavior of the arrow keys - they perform the manual position adjustment. But in normal mode - where, like note input mode. they default you changing pitch - you can absolutely redefine them. The command is called "Pitch up", and you can define any other key you want to perform that function in addition or instead.

While it is true that the up/down arrows can be reassigned to something other than "pitch-up" and "pitch-down", the arrow keys have a few additional uses which are tied to the "pitch-up" and "pitch-down" commands rather than to the arrow keys themselves. For this reason, I would not recommend reassigning them unless the new assignment was made to mimic the arrow key behavior in those other contexts.

Here is an implementation of the commands that you describe. It is done in such a way as to allow the user to reassign the up/down arrows to these commands without forfeiting their behavior for lyrics, other text elements, articulations, and rests. What this means, of course, is that even if these commands are assigned to something other than the arrow keys, they will mimic the arrow key behavior if used with these other element types.

Status fixed PR created

Marc: You were right: I was thinking of Note input mode. I had some recollection of a forum thread where it was said (or so I thought) that the arrows' functions could not be remapped.
And Matt: thanks for your effort. Looking forward to trying it out.

Fix version
3.5.0