Idea for enhancing Insert mode for using in rewriting rhythms
In https://musescore.org/en/node/87151#comment-984255, @cadiz1 challenged me to come up with a simple solution to the problem of rewriting rhythms. I've thought about a little, and maybe I have something that would hit the right combination of being useful enough on one hand, easy enough to implement on the other.
My idea is to leverage the current "insert" command/mode (e.g., Ctrl+Shift+letter to insert a note in step-time note input mode, or the actual insert note input mode), also the "remove selected range" command, which has the ability to delete individual notes/rests. Between these two commands, we already have the code we need to push notes around (eg, when inserting a note, the subsequent notes in the measure get moved later; when removing, they get moved earlier). I also have a pending PR (not one I was originally all that enthusiastic about, but it's interesting and relevant here) to implement a new "change duration of selected note" command while in note input mode - see https://github.com/musescore/MuseScore/pull/5505.
Somehow it seems we could combine these ideas and create something useful.
So, what if, while in note input mode, you move the cursor to an existing note, select the desired duration on the toolbar, hit the magic "change duration" command, and it changed the duration of the selected note and also moved the subsequent notes in the measure later/earlier, and adjusted the measure duration? My current PR adjusts the duration of the note but does so in the usual way - adding rests or "eating" some of the next note(s). Implementing that would not be too bad since all of the needed code is there already - at worst, it might mean a bit of refactoring.
A sneaky way to do it even more simply would be to have "change duration" code actually delete the current note (using the existing "remove select range" command) and then insert a new one (using the existing "insert note" command). In fact, you can almost do this already, except we don't support "remove selected range" while in note input mode. I wonder how hard it would be to start supporting that, as a first step?
BTW, one thing that rarely if ever comes up in these discussions - what do people expect to see happen to other staves when editing a measure in this way? If the measure changes duration, the other staves will need be adjusted as well, and pretty good chance whatever we do to make that happen will be something you don't want (regardless of what we do). That might well limit the usefulness of this approach. The more general "scratch pad" idea that gets tossed around some is certainly much safer, but designing it well is the trick there.
Comments
Well first of all thank you Marc for looking into this. I think the first suggestion (I understand the other one a bit less at the moment, and being forced to activate the insert mode command each time is perhaps heavier) sounds the best, for me at the moment.
Namely, I quote: "So, what if, while in note input mode, you move the cursor to an existing note, select the desired duration on the toolbar, hit the magic "change duration" command, and it changed the duration of the selected note and also moved the subsequent notes in the measure later/earlier".
I think this is the general idea we are looking for: the use of functions and shortcuts already known and implemented (Q/W, and Shift/Q and Shift/W) but with this new fundamental ability to move the following notes earlier/later in the measure (without "eating" the notes)
And as for what's happening in the other staves, I don't think that's the main request, from what I've read on the forums anyway. Let's just say it's not on the agenda, for the moment anyway.
Keep thinking about it, and when you've written the code, let's give it a try. We'll be there!
In reply to Well first of all thank you… by cadiz1
I think it is important to understand the effect on other staves, because it could very well mean the idea is useless and not worth the time it would take to implement it. So I ask people to try the following in a score with multiple staves:
1) find an existing measure where you want to change the rhythm on just one staff
2) for any note where you wish to change the duration, select it, hit Ctrl+Delete to remove it, then go to note input mode, and use Ctrl+Shift+letter to add a new note of the desired duration - this is more or less exactly the same as what my proposed command would do
3) repeat step 2 for any other notes whose durations you want to change (presumably, you will change at least two durations so the measure duration is back to normal)
4) check the notes of that measure on the other staves, and see if you like what happened to them
In reply to I think it is important to… by Marc Sabatella
Well, right off the bat, you're setting an example that people won't want (I suppose). At this point, we are at an impasse. I rephrase my request.
Currently, in input mode, with the shortcut Shift + right/left arrows, I can move (for example, picture below) very easily the third beat (note E) to the first beat (result second measure)
Which I can't do, except edit, retype, edit the rhythm, or cut and paste, with measure 3.
So my question is: can I (or not, in this case, forget about my request, never mind) change the order of notes and rhythms within a measure, and with the same shortcut (or equivalent) to get the result in measure 4?
In reply to Well, right off the bat, you… by cadiz1
Enhancing the existing “swap notes” command to work when durations differ would not be very hard. but to me that is a different problem than the one originally discussed - keeping the original pitches but changing the rhythm. Both are useful, sure, but it’s the problem of changing rhythms that comes up much more often than the problem of swapping notes, so that is what I was focusing on.
In reply to I think it is important to… by Marc Sabatella
Hi Marc and @cadiz1.
Back to MuseScore after a long period, I'm pretty excited by the fact we now have an insert mode, and the perspective that it can be improved! So thanks for this.
I've been following the discussions, and also started compiling and testing some of the pull requests including 6238. I hope that with time I will be able to help a little on coding, but for now I am just exploring the (huge) code again.
So I tested the steps above on 3.5 beta, and also tested the implementation on pr/6238. I think it's a good idea to just allow ctrl+del on input mode since the code is already there, although I definitely wouldn't use it as is directly on a multi-part score because of how it affects other staves. It is, however, useful to reshape (re-rhythm) music material by working on a single staff file then pasting the result into a score.
The ideal solution for those who like that kind of workflow (I love it) would be what in fact describes "Insert Mode" in MuseScore's handbook:
Insert: (Called "Timewise" until version 3.0.2) Insert and delete notes and rests within measures, automatically shifting subsequent music forwards or backwards.
When I read that description I ran to install and test MuseScore, for that's what I was missing all this time. Except the "backwards" part doesn't really work. However, deleting notes and rests doesn't shift subsequent music backwards, and also changing notes durations still either "eats" subsequent music or inserts rests.
So the only way, for now, is to use ctrl+del to manually delete unwanted notes and rests. Sorry if I am just repeating what everyone knows so far.
And then, there's this problem about what happens to the other staves, either inserting or deleting material.
I know it can feel a little off from how MuseScore handles things, but I think that, in the future, notes and rests should be able to be inserted/removed (or their durations changed without inserting rests or "eating" notes at right) only on that particular measure and staff. The plus/minus indicators should show only on the incomplete or "overflowing" staves, so the composer can work on the material of each part not worrying about destroying other parts of, say, an orchestral score.
If I go on dreaming of the future, I would think of not having an "input mode" button (as it is being discussed) and in that case, I would rethink "Insert mode" as a toggle that affects how several of these tasks (change durations/inserting/deleting) are accomplished. I can think of many scenarios in which this would be extremely useful. For that, there should be a version of "Remove selected region" that removes only what is really selected, leaving other staves unchanged.
In reply to Hi Marc and @cadiz1. Back to… by elerouxx
Thanks for your interest on this thread.
"notes and rests should be able to be inserted/removed (or their durations changed without inserting rests or "eating" notes at right) only on that particular measure and staff."
That's my point, too. And it's the way how works Guitar Pro (I don't know for other programs) ie, the change impacts only the current measure and staff.
The only problem is to implement it! :(
"and also tested the implementation on pr/6238"
For reference, you talk about this "suggestion" (#306950: Remove selected range should work to delete notes / rests in note input mode) and PR: https://github.com/musescore/MuseScore/pull/6238
In reply to Thanks for your interest on… by cadiz1
That's right, this is the fix I am talking about, sorry if I didn't reference it right.
From a little exploration, I can tell that the way MuseScore handles the data structures for the score doesn't make this implementation easy. If I understand so far, every "move" to insert or remove a single element on a staff would require all the measure to be recalculated, including all tracks (staves and voices), for MuseScore handles notes (chords) and rests as segments of time all across parts in the score. Right?
So, say a rest belongs to measure 1 and track 2 (meaning voice 3 of first staff) and the user removes it, it would be needed to go thru all remaining ChordRests of the measure on that track and move them to new segments, reorganising the whole segment structure for the measure along the elements on other tracks. I mean, of course it's a lot more complicated than deleting a time range but it's eventually doable. No?
In reply to That's right, this is the… by elerouxx
Eventually as in is already done? Yes. Unless I'm missing something about what you are saying, this is precisely what the insert and delete code does already. All that's missing is for the existing Ctrl+Delete command to also work in note input mode the same way it does in note input mode, but again, the code is already there, my PR just enables it. I guess arguably we could also make the existing Ctrl+Shift+letter command work in normal mode the way it does in note input mode, but the need for this seems more questionable, you're putting a note, why not be in note input mode?
The other thing that would be nice to add is a "change duration and do the same sort of automatic fixup of everything else" command - eg, lengthening a note would lengthen the measure and move the remaining notes to the right, shortening a note would shorten the measure and move the remaining notes to the left. This is precisely what happens if you first delete the note then insert it with the new duration. So really, the underlying code for this is already there. But it isn't necessarily organized in a way that makes actually adding the new command trivial. Probably things would need to be refactored a bit. But should totally be doable.
In reply to Eventually as in is already… by Marc Sabatella
As I replied first, it is already done and works fine when in a single staff. Kind of a scratchpad mode.
The problem, as you questioned yourself, is what happens to the remaining staves when either inserting notes or rests, or by "removing region". It kind of defeats the purpose of "Insert Mode" in most scenarios I can think of.
So, as I see it, lengthening or shortening a note should move the remaining notes to the right or left, but should not lengthen or shorten the whole segment across all staves and voices. The "fixup" actually needed would be to preserve the other tracks. The idea is to be able to (more quickly) rework the material in one voice of one staff at a time regarding rhythm, as easily as it is regarding pitches.
In reply to As I replied first, it is… by elerouxx
So, how to avoid the nightmare of different durations in different staves for the same measure?
In reply to So, how to avoid the… by Marc Sabatella
Well, first of all sorry to put my nose so quickly on a discussion like this when I'm just scratching the surface on the code and on what is happening on the discussions lately (by lately I am talking about the last 8 years).
I can see that suggestions like these keep coming recurrently with different names, like "scratchpad mode" or "similar to insert on a Word processor", and giving different references of how other apps do things, which I am trying to avoid. But I feel that such a mode would add a lot to some people's workflow and I guess I'm one of those too.
What I imagine is not such a nightmare. It's actually simple and it sums up to preserving the material on other staves, and let the modifications to the tail, if needed.
I've tried to put some examples together on this picture.
(EDIT: please ignore the bad grouping and beaming on (b). I made that example very quickly.)
Scenario 1: Given the original material (a.), I would like to rework the Violin II part like in (b.). So I would like to be able to change the duration of the notes and insert a rest (in red) without having to rewrite everything. The quarter rest at the end of the measure would be added if needed. (Currently, your PR would help me do that if I copied this somewhere else, used insert more, changed durations and ctrl+del the unwanted rests and then paste it back. But, long term, working in-place would be just great. Also, remember this is a very simple example, actual cases would be much more complex).
Scenario 2: I inserted a quarter note (red note) in the original material. However MuseScore added a rest (purple) on that 'segment' on the other staves (c.) If I am reworking one voice, I would have little use for that. I'd prefer that the other voices are preserved. If needed, incomplete measures would be filled up with rests at the tail, like in (d.) (*more thoughts on this later).
About what would happens next with that big measure in (d.), there are some possibilities. One of them is that I go on in my reworks, and turn the last two quarters in the first violin to eights (e.) and now the measure is properly closed (maybe I would have to delete rests at the tail, depending on how it works).
Another possibility would be to add a barline before the exceeding quarter in (d.) so it would split the measure. I believe you mentioned it on a discussion about a "scratchpad mode". And actually, It can be done by "split measure before selected notes".
(*Some thoughts about this next)
In reply to Well, first of all sorry to… by elerouxx
While writing this, I was thinking that this concept would be easier to try over a "horizontal first" structure as MusicXML, and it occurred to me to export the score to musicxml and do the modifications there, to see what MuseScore does. The results were exactly what I would expect to accomplish on an "Insert Mode", as in the above scenarios.
I exported the original file, then edited the xml file.
In xml, measure 1 I inserted a note (actually I duplicated the blue note) without editing any other details of the measure. MuseScore added the gray rest at the end of Violin II when re-imported the file.
In measure 3, I deleted the first note (in red), so the measure was incomplete. MuseScore added the gray rest at the end of that measure.
In reply to Well, first of all sorry to… by elerouxx
I'm sorry, I'm not really following that - too many different variations. Can you perhaps simplify to show just one example? I was with you as far as wanting to change a) to b) in Violin II. I got lost as soon as a mysterious "E" showed up for no obvious reason in Violin I. I guess that's part of an unrelated scenarios, but I'm still trying to understand step by step what you imagine happening in the first and what the effect at each step would be on the other staff.
In reply to I'm sorry, I'm not really… by Marc Sabatella
Ok, I'll prepare a step by step example soon.
I have been exploring the code. The main problem to face when implementing this, or any other "horizontal-wise" operations (i.e. freely editing a staff contents back and forth while leaving the others unchanged as far as possible) seems to be that, in each single operation, you have to deal with a data structure that was thought in vertical segments all across the score's staves. Quite the opposite of structures like MusicXML or Lilypond, for example, in which it would be a matter of basically inserting and removing data.
That's why I made the second example by just modifying sequential data in a exported MusicXML file then re-importing it to MuseScore so it handles the structure conversion, and it works as an example of how it should work from the user side.
In reply to Ok, I'll prepare a step by… by elerouxx
This topic has suddenly moved in the right direction :)
See (and try) this plugin, thanks to @Ivr124 : https://musescore.org/en/project/duration-editor
See also this another discussion related to its implementation : https://musescore.org/en/node/321244