Rest Grouping in Pickup Measure
When you create a pickup measure with three 8th notes, the grouping of the rests is off - a quarter rest followed by an eighth rest, whereas it should be an eighth rest followed by a quarter rest. This also causes other grouping problems with eighth and sixteenth notes. See the attachments. The first is what is the case, the second is what should be the case:
Attachment | Size |
---|---|
Grouping_problem.png | 12.29 KB |
Grouping_problem_(2).png | 11.74 KB |
Comments
Confirmed, please file in the issue tracker, best with a sample score
This is a known issue, but not really a bug. The problem is we really don't the difference between a pickup measure versus any other irregular measure. For instance, you might have a 4/4 (nominal) measure in a hymn that you are splitting into 3/8 (actual) at the end of one system and 5/8 (actual) at the start of the next because that's how the phrasing/lyrics works out. This 3/8 measure needs to start with the quarter, but the 5/8 measure needs to start with the eighth. We don't have any good way to know the difference - whether the partial measure is representing the first or second half of a split measure. And that's basically what a pickup is - the second half of a split measure. We can apply some heuristics to try to guess - like, say, assume any measure at the start of the score or immediately after a system, page, or section break should be treated as a second half, anything else as a first half. We actually do try things like this with regard to swing playback. but it's just kind of guessing really.
Anyhow, bottom line for now is, you need to enter the rests you want manually.
In reply to This is a known issue, but… by Marc Sabatella
Well, we have: the 2nd part of such a split measure is (or rather should be) excluded from measure count.
At least we could use that as a way to tell them apart, can't we
In reply to Well, we have: the 2nd part… by Jojo-Schmitz
I don't think that's as reliable, people might just as well exclude the 1st part instead. In fact, that's a known (to me, anyhow) technique to control whether the measure number at the beginning of the next system appears on the partial measure or on the first full measure.
In reply to I don't think that's as… by Marc Sabatella
Indeed, and in those cases that excluded one is the 2nd half, the 1st having being at the end of the previous system.
Oh, now I see what you mean. If you want that 2nd half do have a measure number then yes, bad luck
In reply to Indeed, and in those cases… by Jojo-Schmitz
Right. Both are valid, I've seen people argue for each, with published examples. So for now at least I'm happy that is a way of getting whichever result one wants. But it does mean you can't necessarily rely on exclude always being applied to the second half of the measure.
On the other hand, it doesn't need to be perfect to be worth doing, just needs to be better. At least the current scheme has that going for it at least. But better is to be predictable and actually right more than half the time.
In reply to Right. Both are valid, I've… by Marc Sabatella
Pickup measure (at start of score and so by definition 2nd half and excluded from measure count) should be by far the more common than the case you have in mind with spit measure at system break but 2nd half not excluded from measure count just to see the measure number at the start of the system rather then the next measure.
In reply to This is a known issue, but… by Marc Sabatella
"This 3/8 measure needs to start with the quarter, but the 5/8 measure needs to start with the eighth."
Does the 5/8 measure need to start with the eighth because its the second half, or because its 5/8? It would seem that it's because its the second half, and if that's the case, then the pickup measure should behave the same way - but it doesn't. The pickup starts with a quarter rest, not an eighth rest.
In reply to "This 3/8 measure needs to… by pianocomposer321
rests have nothing to do with this (and, while the title says so, you sample images don't have any rests), only notes (shorter than quarter) that have beams do.
Rest grouping is an entirely different issue, with no solution anywhere, beaming though does have a solution (normally, in full measures) via the time signature properties
In reply to rests have nothing to do… by Jojo-Schmitz
See the title of the thread: "Rest Grouping in Pickup Measure". ;-)
In reply to See the title of the thread:… by pianocomposer321
See your images, no rest in sight
In reply to See your images, no rest in… by Jojo-Schmitz
I'm the one who opened the issue, so I think I know what it's about.
The images were for clarification. I knew I would have a hard time explaining the beaming issues, but the rest problems are easy to explain, so I didn't attach a picture of the rests.
In reply to See your images, no rest in… by Jojo-Schmitz
But you are right, beaming is a bigger issue. That doesn't change my question, however. It affects both the beaming and the rests the same way.
In reply to But you are right, beaming… by pianocomposer321
OK, only there's no solution in sight for rests at all, and this is not only restricted to pickup measures, but also to all compounbd time sigs, like 6/8, there you should automatically see dotted quarter rests but don't.
Beaming and rests are really is 2 entirely different problems
In reply to OK, only there's no solution… by Jojo-Schmitz
I see no reason the same code couldn't be used in the place where rest grouping is performed - it's a simple matter of calculating that offset and factoring it in to the calculations that are currently based on beat position.
A one-line change, add the calculated offset value to the beat position when generating rests. This is totally different than the problem of grouping of rests for compound versus simple meter. Same code I gues,s but totally different issue. Although FWIW, I don't think that's a hard problem either, it's just that no one has bothered to solve it yet.
In reply to I see no reason the same… by Marc Sabatella
The place in the code that deals with beaming is in close vincinitiy to the code that deals with rests?
In reply to The place in the code that… by Jojo-Schmitz
No, like I said, the fix would need to be applied in both places. But it's the same fix. To be specific:
1) We develop a function that calculates the proper time offset for any given measure, perhaps based on the algorithm used for swing, or perhaps something better. The idea is that for any measure considered a "first half of measure", it returns 0, but for anything considered a "second half of measure", it returns the duration of the missing first half. The current swing algorithm subtracts the actual duration from the nominal duration, which makes as much sense as anything else to me.
2) Now that we can get the time offset for measure, we apply that offset in any calculations where we need to:
The new function is at most half a dozen lines or so, the three places where I say we factor this value in are one or two line changes each.
None of this helps in any way with the completely unrelated problem of how we generate the rests in 6/8 or other compound meter. That isn't a problem of detecting the start beat; it's a problem of the code needing to actually generating a totally different sequence of rests, not just the same sequence it already does but starting from a different beat. That is, considering the case of a pickup of three eighths in 4/4, MuseScore already does know how to generate an eighth rest followed by a quarter rest if it understands it is trying to generate rests starting on the "and" of "3". If you enter a half note followed by an eighth note into a 4/4 measure, MuseScore absolutely gets this right. So all we are doing is telling MuseScore to treat the 3/8 pickup in the same way it treats that case. MuseScore knows "eighth quarter" is the right sequence for 4/4 when starting on beat 3&. it just doesn't know this pickup should be treated like it starts on beat 3& rather than beat one. So that's what the online change I mention will do - tell the rest-generation code, even though it looks like the beginning of the measure, it's really beat 3&, now do your thing the way you already know how.
In reply to No, like I said, the fix… by Marc Sabatella
Thanks, Marc, that helps a lot.
In reply to No, like I said, the fix… by Marc Sabatella
I know this is somewhat unrelated, and I'll start a new issue if that would be better, but is there any way I can help contribute this code? I've been learning a few programming languages (mostly python and C++; MuseScore is written in C++, is it not?) for some time now, and I really would like to contribute to a worthwhile open source project, and MuseScore is about as worthwhile as it gets if you ask me ;-).
In reply to I know this is somewhat… by pianocomposer321
Yes, that would be awesome :-) Click "Contribute" above, then "Development", and you'll see some good info. Somewhere within that is the info on joining the developer chat on Telegram, which is probably the single most useful bit of info there, except maybe the instructions on the Git workflow and how to compile MuseScore.
Oh, and yes, MuseScore is in C++. Since I just outlined exactly what needs to happen, it probably would not be hard for you to take that and run with it, we'd just need to show you where the relevant parts of the beam-grouping and rest-generating code are, and Telegram is a good place for that kind of discussion.
In reply to Yes, that would be awesome :… by Marc Sabatella
My web filtering software is blocking telegram b/c its a chat website. I may be able to get it unblocked later, but for now, could you just point me to the correct file on GitHub? I'll at least take a look at it and if it looks like more than I can tackle without asking other devs, I'll wait until Telegram is unblocked.
Thanks
In reply to My web filtering software is… by pianocomposer321
FWIW Telegram has native pss for most platforms too, that's what I use on Windows, Chromebook (maybe using the Linux app? I forget) and my iPhone.
Anyhow, libmscore is the folder for everything relating to score rendering. rendermidi.cpp is where you'll find the function I mentioned that does the offset calculation for swing playback, literally a handful of lines of code whose bottom line is calculating the value of a variable called "offset", and then adding that value to the "tick" (time position) of the chord it is trying to decide what to do with.
So, with a function that takes a measure as a parameter (or, more to the point, a method of Measure class, defined in measure.h/measure.cpp) returning a Fraction to use as the offset (eg, 5/8 would be the returned offset for a 3/8 pickup in 4/4 time because it's logically the second half of the measure, but somehow still returning 0 for a 3/8 partial measure at the end of a system because it's logically the first half of a measure, I have no opinion on random 3/8 partial measures elsewhere), you would need to call that function and use that value in the following places:
1) groups.cpp, in endBeam(), which decides if a chord ends a beam group. The calculation is based on the tick of the chord, we'd need to add the calculated measure offset. Probably everywhere you see cr->tick(), replace with a new local variable adjustedTick, which you'd calculate at the top as cr->tick() + the return value from your function. Might be other places too, but that might turn out to be it, not sure. Certainly it's relevant though.
2) edit.cpp, the function setRest(). Here the tick is passed in as a parameter, and then for some reason immediately copied to a local. I literally think all you need to is add the calculated measure offset during that assignment. But I'm not sure why that originally parameter was passed by reference, could be something non-obvious going on.
In reply to FWIW Telegram has native pss… by Marc Sabatella
Hey marc, sorry I haven't started working on this yet, I just decided to get started. Re-reading your posts here I can't figure out how I'm supposed to determine whether the measure is the first or second half. All I can find you explaining is how to calculate the offset if it is the second half. Am I missing something?
BTW, I will join the telegram group asap.
In reply to Hey marc, sorry I haven't… by pianocomposer321
Hello! The most relevant part of what I wrote before was this: "We can apply some heuristics to try to guess - like, say, assume any measure at the start of the score or immediately after a system, page, or section break should be treated as a second half, anything else as a first half. We actually do try things like this with regard to swing playback. but it's just kind of guessing really." It's not going to be an exact science, there really is no way to know in general. But this is the basic approach sued by the swing playback code, the same approach could be used here.
In reply to OK, only there's no solution… by Jojo-Schmitz
There may be problems affecting rests that don't affect beaming, but in the context of this issue, they are affected exactly the same way. We're not talking about dotted quarter rests in 6/8, were taking about quarter and eighth rests in pickup measures.
In reply to "This 3/8 measure needs to… by pianocomposer321
Indeed, pickup measure is second half of measure, and all second-halves-of-measures should behave the same way. The problem is there is no totally way to tell if a measure really is meant as a second half - best we can do is guess based on the sorts of things we are discussing (presence of breaks, use of exclude from measure count, etc). BTW, another reason not to rely on the exclude from measure count option is tons of people don't use it - they number their pickups 1. Not saying it's right, but it's common.
BTW, unless I'm mistaken, the basic issue is identical for rests as for beaming The code might differ, but the basic issue is the same. And as I mention, for swing playback. We partially solved it there, I think, and if I'm remembering and reading the code right, we just used the line break methods (see Score::swingAdjustParameters() in rendermidi.cpp, where the comment says "adjust for anacrusis"). Probably there should be a single function that handles this and gets used for swing, for beaming, and for rest grouping.
In reply to Indeed, pickup measure is… by Marc Sabatella
I apologize, Marc, I misread your post. I was just skimming and it looked at first like you said that this was fixed for measures that were split across systems.