PruneStack - Selecting levels of chords or switching voices of levels

• Jan 25, 2022 - 03:42

I had use for attempting the PruneStack plugin (https://github.com/birdwellmusic/PruneStack) today.

It seems that changing voices wasn't working well. For example, selecting only the first level (lowest notes of chords in a range) and effectively determining to want these to be in voice-2, the provided functionality didn't actually do this. The plugin was only selecting the end of the selection or something funny, and the code itself had similar comments mentioning such due to some limitations. Pruning worked great though.

I went ahead and altered the QML so that the levels can be switched to a selected voice. After getting that to work, I realized that sometimes maybe I or another might want to not just switch the voice of whatever level of chords in a range, but rather perform some other task like octave shift, visibility, change notehead style, etc. Who knows? So I also put in another button that merely selects the results from a given range and checked level(s), resulting in list-selection (of noteheads) without any other action taken. Further commands can be issued within MS from there. Hopefully it may find some use besides meself.

BTW, I've seen plenty of posts in the past asking to be able to select all bottom notes or top notes of chords. I'm not sure if this will be the exact type of thing since "top" here is sort of relativistic depending on the amount of notes in each chord in the range, but this potentially could help someone. Bottom is always level 1.

If anyone tests it and finds something funny going on, it would be appreciated if some responses were made here. Lucky ducky Dorico 4 users have this stuff already built-in...

P.S. This kind of plugin is benefited from having a shortcut assigned to it when doing some arrangements or whatever.

P.P.S. Download @ https://musescore.org/en/project/chord-level-selector


Comments

And here's a screen-cast of some things related to this plugin. Notice that if in the selection multiple voices already exist, a "level 1" still picks up both, as they are both independent chords:

UpdatedPruneStackDemoColor2.gif.gif

Update: "Top" is such a desirable level to select (rather than some specific layer as a number), and figuring that it must be easy to accomplish, I got that taken care of in an update and reworded the buttons so that they read as [select only], [revoice], [delete]. In essence, [select only] is the main function with [revoice] and [delete] being mere helper functions. That is, a user can easily press DEL on keyboard or use the voice buttons/shortcuts after making a selection, but figured might as well keep those in the plugin anyways. Should've done this back in 2016 when the plugin was initially offered (thanks again to OP)! Also, I sacrificed level 8 for Top and level 1 for Bottom as available options:

UpdatedChordLevelsDemonstration.gif

Update 2: Apparently you can use keyboard input with the QML plugins (didn't upload the qml to forum yet), but it seems that focus has to be set manually for it to operate. So, setting a button's focus property to true prepares the QML window for keyboard input and can receive key strokes. Point is, you can 1) set a plugin like this to be invoked by a shortcut through musescore, and then 2) use keys like 0-7 for layers of selection... This is pretty slick compared to not having it at all. Again, it's too bad MS didn't have this already built in. MS4's gotta have this in it natively or at least as a plugin in its beginning releases

Update:
Allowed for formation of a chord or a sequence from a range selection (staves + voices taken into account). Although this is different functionality and could be separate, I figured why not since it's easier to make use of all this in one plugin for me personally.

So now: keyboard shortcuts work for levels (0 for top and 1 for bottom I think it was) + 8 forms a chord + 9 forms a sequence. They get stored into the clipboard so a paste will apply the results: a chord will default to a quarter duration and a sequence will default to an eighth duration. I hope someone finds some sort of practical use, but even if not, I'll use it on occasion. Here's a demonstration (made use of retrograde plugin also for the hell of it):

ChordSequenceFormationRetro.gif

In reply to by worldwideweary

Hmm, I don't seem to be able to get this new version to work on my system (Windows 10). It doesn't show up in Plugin Manager so I can't even attempt to select it. (Previous versions have been fine.)

I've tried loading it into Plugin Creator and running it from there but it fails with an error message:
Running…
Creating component failed
line 190: Expected token ;'
line 190: Expected token
,'
Looking at it in a text editor, line 190 seems to be the line:
let uniquePitches = [...new Set(pitches)];
but I don't know enough about QML coding to know what might be wrong with that. I've had a quick search on the web looking for information on QML syntax but I didn't find anything that seemed to be useful.

I've found the previous versions very useful and a nice extension of the original PruneStack concept so it is a shame that I can't get this new version to work for me. I wonder if you have any ideas what might be going wrong for me.

In reply to by MarkWWW

Thanks for the feedback. Off hand, I don't know what could be wrong, as it works fine for me on my Linux distribution. That particular line is to avoid duplication within an array of pitches for the extra two functions as shown in the most recent demonstration. Sets don't allow for duplicates, so the conversion from an array to a set and back to array is a quick/easy way to do so.

Maybe there's something up with Javascript version compatibility in MuseScore's build system for an older Qt version...

Try the following attachment and see if it works, as it appears to work for me. I'm just using
= new set(); instead of [... new set()]; here.

If that works for you, I'll replace the main attachment with this one.

P.S. I kind of ran out of room, which is why I removed the "delete" button instead of trying to move things around. I figured since delete is so easy to execute (literally press delete) after making a level selection, that it's not important to have as a button that does both at the same time). So now this is even lesser a "pruning" plugin and more of a selection filter besides the extra two functions

Edit: Attachment removed for the sake of having reference to the main plugin page instead for download

In reply to by Jojo-Schmitz

Aha! That's got it.

Yep, all working nicely now on my Windows 10 system using the version of the syntax without "let". Many thanks both of you for finding and resolving it so quickly. In truth I'm not sure if I will ever find a need for the new chord/arpeggio feature, but you never know and it's always better to have a tool and not need it than the other way around.

And as I said, the other features of the PruneStack/ChordLevels idea have been very helpful, so many thanks again.

One thing I will just mention while I'm here - I notice that if I run it from the Plugin Creator there are a lot of "Warning: QFontEngineFT: Failed to create FreeType font engine" in the bottom window after the plugin is closed. I don't know if this is indicating a real problem or is merely cosmetic (it doesn't seem to stop the plugin working in any way) but I just thought I'd mention it in case it is important.

In reply to by Jojo-Schmitz

Apparently "let" was introduced in 2015, so that means whatever version of Qt the Windows build used was older than that... (5.9). Not that important, as it only keeps a variable in the particular context only (otherwise var gives those warnings of already being declared in the same function even if in different code blocks, unlike C/C++). Useful when testing when not in different functions. JoJo's probably right about ECMA6 (ES6).

As far as the font engine,... maybe similar situation. Non of these problems or warnings are in my local build using Qt 5.12.12.

In reply to by MarkWWW

P.S. The plugin has its own little project page - https://musescore.org/en/project/chord-level-selector

MarkWWW, if you would, try out the file attached over there instead of here. Apparently the extra chord/passage functions needed an update also after testing a few things. Even though you don't find a use case now, better to have them functional if and when you desire to use them :)

And thanks again for the help.

In reply to by worldwideweary

I've now had a chance to look at the latest version from the project page and it does now work as far as the original functions (0-7) are concerned, but unfortunately neither of the new functions (8 or 9) seem to work properly for me - they both just seem to cut the notes in the selected range to the clipboard. You can then paste them back, but they come back just as they were before, rather than assembled into a chord or spread into a sequence as they are intended to be.

Let me know if there is anything else you want me to try and I'll see what I can make of it.

Thanks again

In reply to by MarkWWW

Weird. It's working for me. I will attempt to get access to an older build built with Qt 5.9 and test within Windows. Thanks for the feedback.

By the way, are you using MuseScore 3.6.2? Also, make sure that that's the behavior when running the plugin as an actual plugin and not in the Plugin Creator mode, since I've found that in dev mode the shortcuts require to click-focus onto the plugin's interface when running first, otherwise quite literally whatever MuseScore's 9 or 8 or whatever will end up being run rather than the plugin's shortcut, which might be merely selecting a duration.

In reply to by worldwideweary

While I'm up, I found a scenario of a problem: I'm doing:
1) Copy of range selection
2) Delete it
3) Perform the create function(s) and apply results to score
4) Then form a range selection around the results
5) Perform a swap of the original with the results on the score
This seemed to work just fine for most situations, but I realize now that swap only swaps to a certain degree. That is, the length of the original range-selection and up to that is as far as it'll go. If the results were past that, then swapping will end up keeping them there which is not desirable. I switched out swapping to just do a series of undos after a cut, and it is working better on my end

But I haven't tested on Windows + Qt 5.9 so not sure. If you have extra time, a test would be appreciated until I can try a Windows system! Thanks

In reply to by worldwideweary

Yep, I'm using MuseScore v.3.6.2 and testing with it running as a real plugin in Plugin Manager (not in the Plugin Creator window). I've just downloaded the latest version on the project site (ChordLevels3x_4.qml) but I'm still getting the same behaviour - pressing 8 or 9 cuts the notes from the selection but when you come to paste them somewhere you just exactly whatever was in the original selection, not a chord or sequence of 8th notes as is intended.

In reply to by worldwideweary

Ok, after checking the default build in a Windows environment, the error messages show me that apparently ES5 (pre-2015 javascript) doesn't have includes() function nor sets. Gotta remove duplicate pitches by hand, it seems. If you've the time, please try the new attachment in the project link! If you get any error messages or something, please mention it.

Thanks again for your co-operation.

In reply to by worldwideweary

Using the new version (ChordLevels3x_5.qml) I now get different behaviour, but still not what I am expecting.

When I select a range of notes and run the plugin and choose 8 (or 9) I now get apparently nothing happening at all. The range of selected notes is now left as it was (previously it was as though the selection had been Cut), and the Plugin windows closes. Moving to an empty bar and choosing Paste now pastes nothing (where with earlier versions it pasted a copy of what had originally been selected).

There are no error messages.

In reply to by MarkWWW

Shucks. On my Windows 10 running Musescore 3.6.2, the paste works just fine. Also on my Qt 5.12.12 build for Linux distro. I'm not sure I'll be able to figure out what's wrong without being able to reproduce no pasting. Thanks again though for your testing the plugin. At least the level selectors are working on your setup machine. Would be nice if others can reproduce no pasting occurring with 8/9 functionality, out of curiosity.

Worst case, if you ever wanted that functionality, you could add c-style comments around the cut and undo commands. Results should be that it replaces what you have originally range-selected with the results, but it could overwrite something so it's riskier. Then again, ctrl-z [undo] should be able to be performed without a problem if something undesirable occurs. In other words:

Without a space between / and * (forum acts funny otherwise)
@ line 223 add / *
@ line 228 add * /
@ line 296 add / *
@ line 302 add * /

In reply to by worldwideweary

OK, I've just tried modifying ChordLevels3x_5.qml in that way, commenting out the cut and undo commands and the modified version now behaves similarly to the way it did in the earlier versions. That is, pressing either 8 or 9 now cuts the selected range out of the score and choosing paste pastes it back, but exactly as it was before, i.e. the notes are not assembled into a single chord or distributed into a sequence of eighth-notes as they are meant to be.

It's all a bit of a puzzle.

In reply to by MarkWWW

Weird man, I can't get the behavior you described on my Windows 10 Pro system + MS 3.6.2, and the code reads okay to me so I'm at a loss for now. If I can emulate your results sometime in the future, I'll reply here.

Tell ya what though, I made another pass through the code and made sure to include some semicolons + ()s that weren't there. Maybe that makes a difference depending on system versions or something, as I'm not too familiar with JavaScript and its relation to how Qt's QML functions appropriately. I also verified a few other things that needed an update on the side, and the console prints out the pitches [0-88] that are formed for verification purposes.

If you have the time, (sounds like a broken record), maybe try the new file at the project page.

In reply to by worldwideweary

Curioser and curioser.

I've now tried it with the latest version from the project page (ChordLevels3x_6.qml) and the behaviour is as before with ChordLevels3x_5.qml - nothing appears to happen to the selected range of notes and moving to an empty bar and choosing paste does not paste anything at the new location.

So I next tried it in the Plugin Creator window. I used a two bar string of quarter-notes up and down a CMaj7 arpeggio (C E G B C G E C) as my test range and when I ran the plugin and chose 8 (after first clicking on the plugin's window to make sure it had focus, as you pointed out previously) I got the line:

     Debug: Clipboard chord consists of pitches: 60,64,67,71,72

appearing in the console pane. This seems correct to me - the plugin has correctly determined that there are 5 distinct pitches in the selected range and has ordered them correctly from low to high. BUT, when I attempt to paste it somewhere, nothing appears.

My hypothesis is that the contents of the clipboard are being lost on my system for some reason when the plugin closes, so that there is nothing there to paste. But unfortunately I don't know enough about writing QML code to really investigate this hypothesis properly. And while I can believe that differences like this might occur between say Linux and Windows version due to different QML versions being used, it doesn't explain the difference between what I am seeing and what you are seeing on your Windows 10 system.

All rather confusing, really.

In reply to by MarkWWW

Update: I have another machine with a clean install of WIndows 10 + new download of MuseScore 3.6.2 from the website recently, and now I can reproduce dysfunctional behavior (oh boy). Quick check verifies that it has something to do with the way the cursor is operating. I'll see what I can do to figure it out. As to why this is inconsistent, I have no idea for now.

Update: On said system, I managed to get it to function as intended by changing the rewind expressions to explicitly store the begin tick before performing any further operations, and making use of that storage instead of relying on the current selection's begin tick, so I think maybe the nth-time might be the charm, Alice. Put it this way, I'll be ever-so-slightly-pissed if you say it doesn't work. Check it out if you have the chance.

Still can't explain why older version functions just fine on another Win and Linux system elsewhere (it could be that the other Win system has Qt Creator and newer libraries present on the machine, but that's an uneducated guess). I've also verified this new one performs as intended on the other systems (this time though I'm getting audio playback when forming chords before pasting). Once again, insert message here about appreciation of feedback - otherwise wouldn't have known about the problem. File is updated on the project page (the _7 at the end of the filename is added by the website functionality, not by me).

In reply to by worldwideweary

Yippee!!!

The _7 version is now working for me as expected - 8 and 9 now correctly read the notes in the selected range and allow a corresponding chord or sequence of eighth-notes to be pasted elsewhere.

Once again, many thanks for making this plugin available, and for having the persistence to keep on at it until finally arriving at a resolution.

Do you still have an unanswered question? Please log in first to post your question.