Filling measure with rests be affected by time signature
With all due respect, I'm surprised the algorithm of filling rests is so immature.
For example, under the time signature of 12/8, I want to input like this:
After I input the crotchet, I expect to see the rests be arranged like either of the following (because every three quaver rests are a group):
But instead I see:
The relevant code, if I find that correctly, merely calculate the longest duration that can fit into the rest of the measure, and pushback that into the durationList.
This can cause great inconvenience if the user is inputing under a time signature other than 4/4 or 2/4. What I'm suggesting is that this can definitely be a field to work hard on for the following 3.4 or 4.0 release. I doubt whether I have the time to fix this whole thing since it's the start of a new semester, so I really hope I can get your attention on this issue.
Comments
It's been discussed recently in another thread, there the idea was to reuse the beaming properties of a time sig to determine the rest grouping.
In reply to It's been discussed recently… by Jojo-Schmitz
If that's the best way to fix then I'll leave it to you guys :) Because you know beaming properties (translated to code language) far more than I do.
In reply to If that's the best way to… by Howard-C
Earlier discussion here: https://musescore.org/en/node/286568
I have added a suggestion to the issue tracker #294419: Allow modification of default for filling measures with rests
It's definitely something to improve, but it's been this way for years, it can wait for you to work on it after the semester :-).
Really, in practice, it's not really that big a deal, which is why it has remained this way so long. After all, consider if those same rests were at the beginning of the measure, you'd have to enter them yourself, left to right. Why should rests at the end the measure be different? We get a little spoiled by the fact that sometimes the generated rests happen to be ones we want anyhow. But if are just in the habit of entering all rests left to right just like we enter all notes left to right, it ends up not mattering at all how the generated rests are spelled.
In reply to It's definitely something to… by Marc Sabatella
OK, maybe the way in the second screenshot is not necessary, but at least a semibreve rest shouldn't be there any way because it's weird for a 12/8 measure to have that. I have no other way besides manually input quaver, (dotted) crotchet, (dotted) minim rests from the beginning to the end even if I have no other notes to input in that measure. And I have to do that for every measure and for every part.
Or, if you don't want to input in a standard way, then fine, you can keep the rests at the end as they are. But I prefer a standard way. And I'm pretty sure you want that too.
In reply to OK, maybe the way in the… by Howard-C
Maybe a possible solution could be using toRhythmicDurationList ( https://github.com/musescore/MuseScore/blob/f4c3e75c9479755d8cab58c0dc9… ) to create the duration list when splitting the residual duration of the rest instead of a simple toDurationList.
Ciao,
ABL
In reply to Maybe a possible solution… by ABL
What is the rhythmic duration list?
Well, it uses time signature as a parameter so I guess this is close...
In reply to What is the rhythmic… by Howard-C
From what I understand, every time a note is added or pasted, MuseScore splits it at measure boundaries; the same happens for the leftover of a rest (within a single measure) when a note is pasted or created at its beginning: MuseScore splits this leftover duration into a set of valid durations and then adds to the score the corresponding new rests. The list of such durations is the duration list; a rhytmic duration list does the same thing, but also keeps into account, when creating the list, the beats inside a measure, based on the time signature beaming division options (one of time sig. property).
For example: 4/4 rest in 4/4 time sig.; insert a 3/8 note at the beginning of this rest: the residual rest is 5/8 long; the valid duration list is 1/8, 2/4 (since 2/4 + 1/8 = 5/8), so two rests are added: 1/8 and 2/4.
6/8 rest in 6/8 time sig.; insert a 1/4 note at the beginning of this rest: the residual rest is 4/8 long; the valid duration list is 1/2 (since 1/2 = 4/8), so a 1/2 rest is added. toRhythmicDurationList should in principle give a different list: 1/8, 3/8 (since beam division happens at groups of 3/8) and therefore two rests (1/8 and 3/8) should be inserted.
I hope my hurry explanation (and my English as well) is clear.
In reply to From what I understand,… by ABL
Tried, won't work :(
Am I on the right track: https://github.com/Howard-C/MuseScore/commit/9b20ae0bc8a1b60258b3a9e6a8…
In reply to Tried, won't work :( by Howard-C
I think that the right place is maybe when the filling rests are generated, here: https://github.com/musescore/MuseScore/blob/master/libmscore/cmd.cpp#L8…
Indeed, it is maybe better to split in this way only the auto-generated rests (I fear that modifying setRest maybe splits a user-inserted rest into a set of rests, but I didn't really test it).
I quickly tried modifying cmd.ccp at line 858 and, when inserting a quarter note (from note input mode), it works as expected (i.e. 1/4 note followed by rests: 1/8 1/4 1/8); however, the order of rests when inserting a 1/8 note is not correct (i.e. 1/8 note followed by rests: 1/4 1/8 1/4, instead of 1/4 1/4 1/8); it is again correct when inserting a 1/16 note. I don't know if I did something wrong in giving the parameters to the function (I used the tick defined in line 865) or if the function itself does not work in some "corner" cases.
If we decide to modify these auto-generated rests we have to make sure that it does not make strange things in the case of simple time signatures (for example, creating a set of three 1/4 rests when inserting a 1/4 note at the beginning of a 4/4 measure).
Ciao,
ABL
In reply to I think that the right place… by ABL
Are you suggesting we have to modify toRhythmicDurationList?
And for convenience purpose can you commit your changes, push it and put a link here?
In reply to Are you suggesting we have… by Howard-C
> Are you suggesting we have to modify toRhythmicDurationList?
Not as a first action: this function is used elsewhere in the code and a change could cause breaks. But if a deep investigation finds that it misbehaves for some cases, then it can be modified, and the consequences on other parts of the code must be deeply investigated as well.
Here is my quick test:
https://github.com/AntonioBL/MuseScore/commit/4640e8cda794b03ad8c88de07…
In reply to > Are you suggesting we have… by ABL
Just curious, what made you think of modifying cmd.cpp instead of edit.cpp? Because from line 620 at noteentry.cpp the setRest() function points to the one in edit.cpp.
In reply to Just curious, what made you… by Howard-C
Well, I ran a debug build of MuseScore inside gdb, I made a 6/8 score, and then I interrupted the execution with Crtl+C and set a breakpoint at the beginning of function toDurationList. I continued the execution and inserted a quarter note at the beginning of a measure. The breakpoint stopped the execution twice, and by calling the backtrace I could identify which one was the call inserting the rests (the other one was just verifying that the note would fit inside the measure).
There are probably other ways for achieving the same score result, so, probably, some of them call other functions such as those in noteentry.cpp, but we have to be careful not to modify the funtions changing the user-inserted duration (e.g. if the user inserts a 2/4 duration MuseScore should insert a 3/8 tied to 1/8 instead), but only those changing the automatically inserted rests.
I suspect that the function in edit.cpp could be called (by I didn't verify it) when changing the duration of the rest (e.g. by selecting it and pressing a different, possibly longer, duration).
Ciao,
ABL
In reply to Well, I ran a debug build of… by ABL
How to set a breakpoint?
In reply to How to set a breakpoint? by Howard-C
Depends on the debugger you use. If you're using visual studio or Qt Creator, you can set a breakpoint once in debug mode by clicking in the gutter of in front of/on the line number. A red circle will appear if done so correctly.
In reply to Depends on the debugger you… by jeetee
So is there anyway to show (automatically) what functions are called when performing a certain action in the debug process?
In reply to So is there anyway to show … by Howard-C
When you've hit a breakpoint (= you've set one and the debugger stopped there) look for something called the "call stack". This is the list of all functions currently being called, with the current function on top.
In reply to So is there anyway to show … by Howard-C
If you are using Microsoft Visual Studio under Windows, you can have a look here:
https://docs.microsoft.com/en-us/visualstudio/debugger/debugger-feature…
or here (this link talks about C#, but debugging a C++ program in Visual Studio is basically the same): https://michaelscodingspot.com/debugging-part1/
If you are working under Linux, you can see: https://www.youtube.com/watch?v=bWH-nL7v5F4
The stack trace, or back trace, is the list of functions which have been called to arrive to the point you have set a breakpoint (or in general the point where the program execution has -temporarily- stopped).
Please remember that, in order to have useful information while running under a debugger, MuseScore has to be compiled with debug options (under Windows the default is already ok since it is release mode with debug symbols):
https://musescore.org/en/handbook/developers-handbook/compilation/compi…
Ciao,
ABL
In reply to If you are using Microsoft… by ABL
Thanks! This is really helpful (and confusing, see https://musescore.org/en/node/294580#comment-945960).