A Down and Up Bow Tracker

• May 15, 2024 - 05:30

I write for strings a lot, but one thing I dread about it is having to add the articulation for it. Many a time I would lose my mental note one whether the note was an up or down bow, so adding a tracker on the screen would immensely help my brain! And if this is already in Musescore, tell me please!

I think the best way for it to work would be to show you the symbol at the top of the screen whenever you click on a note.


Comments

In reply to by Heterogina

1) Download the most recent Bowing.qml file above.
2) Move it to your MuseScore plugins folder.
3) Enable it in MuseScore: https://musescore.org/en/handbook/3/plugins#enable-disable
4) Test it out.

At the moment the simplest way to check it out is to use the dropdown option to add calculated bow direction as letter codes to the score, (see image above). Use Undo to clear the texts.

If I'm on the right lines then it will be worth adding the up/down indicator to the plugin dialogue rather than as letters to the score.

What do you think about the situation with slurs?

In reply to by yonah_ag

Ok, I got it figured out, thank you!

Yes, having the actual bow symbols would help out a ton!

The slurs are a problem though. When you slur two or more notes, you're only using one bow stroke, so having the plugin saying "d", "u" , "d", etc. in a slur is incorrect.

I do have to thank you for putting a lot of time in to this for me (well, not just for me, there are a lot of composers who will benefit from this), it means a lot :)

In reply to by Heterogina

The actual bow symbols are to be shown in the plugin's window rather than added to the score, aren't they? The text codes are just for development purposes. It's a pity that the plugin API does not give easy access to the relevant slur info so I'll have to code the workaround suggested by @elsewhere a few days ago.

I have compared the musicxml and mscx formats and decided that the mscx is going to be easy to process for slurs. This file will get info down to the measure number and chord number rather than the tick so I will need to do some re-engineering of the current plugin since it maps everything in ticks! (Alternatively I could try to build a tick tracker whilst parsing the mscx file).

In reply to by yonah_ag

yonah_ag wrote > the plugin API does not give easy access to the relevant slur info so I'll have to code the workaround suggested by @elsewhere a few days ago.

Seems a real shame that the plugin API is limited with unexposed commonplace information, such as slurs. Somewhere down the road, it seems like it would make sense to take on the larger task of expanding the API. And that notion seems worthy of a Github discussion.

yonah_ag wrote > I have compared the musicxml and mscx formats and decided that the mscx is going to be easy to process for slurs. This file will get info down to the measure number and chord number rather than the tick

If you process the mscx (xml) does that mean you'll be creating a plugout rather than a plugin?

scorster

In reply to by scorster

It would make plugins much easier and quicker to develop if the whole object model and all element properties were available.

Processing the uncompressed xml does make it like a plugout but this will all happen from within the plugin code. I will save the xml file programmatically then read the whole file back into a variable for parsing. (This is the way TAB Ring's 3.6.2 compatibility mode works).

Plugin Update 0.5.5

Found some time for a bit more development so here's 0.5.5 which processes slurs via the musicxml export and then incorporates the results into the bowing map. Please do some testing and feedback any issues. My simple test is shown below:

Bowing.png

Bowing.qml

In reply to by yonah_ag

Brief testing here suggests that Add bow text to score is working perfectly.

Given your example it seems there's only the need to address inferences. For instance, one could argue that stroke at arco would be UP because it's on an "and" (in 4/4 meter.) But the reader never quite knows, so then it's up to the conductor or section leader to decide.

Of course the scorist can add a definitive stroke direction but—if they believe the inference is strong—he or she may prefer to omit the clarification, thus keep the score uncluttered by stroke direction marks that should be understood.

Therefore I'm hoping:

• we can define a list of common inferences (for various meters)
• allow the scorist to add staff text objects to enforce a particular direction without explicitly notating it.

. . .

The three Map options look good—though my understanding of them is faint.

How does one remove the d / u text objects from the score?

scorster

In reply to by scorster

• The map options are purely part of my development code and will eventually be removed.

1) Full map showed me the score elements available to a plugin.
2) Bowing map is a filtered map of those elements relevant to bowing.
3) Is the bowing map processed into up/down/rest at each score tick.
4) Is 3 realised on the score as it was easier for me to visualise.

The last update adds the 'missing' slurs to map 3 and this is now the basis for the plugin to actually work as requested.

• You can remove the d/u texts with undo.

• If a list of inferences and scorist texts can be defined then they can almost certainly be programmed. As with TAB Ring, I only have the programming skills so I am dependent on you and others to define any musical requirements. 🙂

The next stage is to get rid of all the map options and add a proper UI.

In reply to by elsewhere

I don't see any pedal symbols to delete: shouldn't they show as "Ped"? Since I have never played a bowed instrument I will have to depend on other users to define any implications such as ending a pizz on seeing a down bow symbol. Doesn't the scorer have to end pizz with an arco?

Not sure about the error message as I have never seen this even after multiple runs. What OS are you using? I can only test with Windows 10. Do you still get the error if you delete the musicxml file manually between runs of the plugin?

In reply to by yonah_ag

Right click on the square bracket underneath in measure 4. It's called a Pedal Segment (news to me too) And delete it. I can't reproduce the error message reliably (Windows 10, running from the Plugin Creator), but why are you writing the musicxml file?

In reply to by elsewhere

I'm getting a bit lost here. Your "down bow" appears to be an up bow and your bowed instrument has pedals, (which I am rightly, or wrongly, ignoring.)

Does the 0.5.6 update (above) fix the issue?
Do I need to be concerned with processing pedal symbols at all if they appear in the score or can I safely ignore them?

In reply to by yonah_ag

Just ignore the pedal. You originally opined it might affect the code. It does not.
And see below: 0.5.6 fixes the rest thing, but not the bow after pizz. I said down bow because the plugin put a d above it (EDIT: in measure 1). I attach the file processed by 0.5.6
EDIT: I only ask "Add bow text to score" and don't ask for the maps first. Would this matter?
(EDIT: tested this myself: no effect)
articulate3.mscz
EDIT: I see in the code (lines 224 & following) that you identify up & down bow by a number. Could that not be a MU3.6 - 3.7 difference as we encountered before? (Where do you get these numbers?)

if (info==2652) {
info = "Down bow";
tick = elm.parent.parent.tick;
zelm = true;
}
else if (info==2677) {
info = "Up bow";
tick = elm.parent.parent.tick;
zelm = true;
}

In reply to by elsewhere

I only ask "Add bow text to score" and don't ask for the maps first. Would this matter?
No, this makes no difference.

I see in the code (lines 224 & following) that you identify up & down bow by a number. Could that not be a MU3.6 - 3.7 difference as we encountered before? (Where do you get these numbers?)
Could be an issue. I'll check. These codes come from the ObjectExplorer plugin

However, in your post of Jun 22, 2024 - 01:14, you say " bow down in measure 4" but your image shows an up bow. Was this a typo? See https://musescore.org/en/node/364096#comment-1247335

In reply to by yonah_ag

!!!@!!!@!!!

The bowing codes are different between MS3.6.2 and MS3.7.0.
What a nuisance. I wonder why this was necessary.
There appears to be no other property available to the plugin API for identifying these symbols so I will have to add some version specific tests.
BowingCodes.png

In reply to by yonah_ag

In https://musescore.org/en/print/book/export/html/76

I found this interesting bit of code:

var s = newElement(Element.ARTICULATION);
s.symbol = "articAccentAbove" // see SymId enumeration values
curScore.startCmd()
c.add(s)
curScore.endCmd()

Could that not be used instead of the numbers?
I tried to paste it in your code but didn’t get any console.log output

Interestingly:
From the documentation I pulled
enum SymId {

into Excel and forced items 1 per line and
stringsDownBow appears at line 2534
and stringsUpBow at line 2551

EDIT: Or get the bow info also from the musicxml file, now that you have the hang of it...

In reply to by elsewhere

Thanks, that looks hopeful. I'll try the enum route first. No idea why console.log didn't work.
If I knew at the start what I know now I would've done the whole process via musicxml. A half-baked plugin API can be so frustrating – but understandable in a non-commercial product.

In reply to by elsewhere

Oops!

That write is a debug for me to inspect the state of play after the regex. I will remove it now that the regex is working. (You can open that file with a text editor to see what the regex has done).

Is there a way to generate the musicxml contents directly to a variable rather than exporting to a file?

In reply to by scorster

Hi. I am back with my string-playerness :P
Bowing markings can be put inside a slur to indicate a smooth change of direction so that one would not run out of bow. This would be hard to program I think, but basically a bowing marking within a slur would interrupt and divide the slur at a given point.

In reply to by yonah_ag

A new mystery: Bowing 0.5.8 runs notably slower than previous versions: 5562ms vs 41ms on my testfile. Seems like MS is incredibly slow at finding the symID (?!)
EDIT: I put a timer at line 373 and get the following output:
Running…
Plugin Details:
Menu Path: Plugins.Bow Direction
Version: 0.5.8
Description: Bow Direction
Requires Score
Debug: 373: 5661ms !!!!!
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 1ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 1ms
Debug: 373: 0ms
Debug: Process: 5709ms

but running again everything is fine

Plugin Details:
Menu Path: Plugins.Bow Direction
Version: 0.5.8
Description: Bow Direction
Requires Score
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 1ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: 373: 0ms
Debug: Process: 44ms

In reply to by elsewhere

Did some more tests:
onRun: {
console.time("109");
//var info = SymId.stringsDownBow
//var info = SymId.stringsUpBow
 var info = SymId.sixStringTabClef

    console.timeEnd("109");
    Qt.quit();
}// end on Run

Each of these info lines takes 5 sec on the first run, 0 sec thereafter. It must relate to reading something into memory, but 5 sec is an awful long time. The sixStringTabClef item is early in the table but does not run faster. Maybe we should ask Jojo Scmitz what he thinks about this...

In reply to by Asher S.

No idea who the admins are. When 1.0.0. is released I will add it to the plugins page. Subsequent revisions will simply use the same page with some release notes as it would generate too much clutter having a new page for each version. GitHub will be used as the main repository.

In reply to by yonah_ag

The following comments pertain to running the Bow Direction v0.6.0 plugin in MuseScore 3.7 onMacOS

I like the plugin's simple UI, but a few comments:

   
• Would it be possible for the plug-in to detect a change of selection? If so, the plugin could update its bow direction display without requiring the user clicking the Bow button. Actually, if so, there would be no need for the Bow button.

• I wouldn’t hestitate to increase the size of the plugin window, particularly to make the Add label more self explanatory. I think the u p r symbols are good but perhaps the plugin could also offer the standard down and up symbols and r:

      Down Up r.png

• Is it possible to keep the plugin as the frontmost window? Or can it be docked?
  

Regarding the plugin's function:

  
The first run appeared to manage a perfect accessment. Then I added a slur. When I ran the plugin with the slur still selected I got an error message about being unable to operate in that state … should have jotted it down!

Afterwards the plugin seemed to ignore the first slur (in the attached score) and believed that a second slur included one note beyond the end of its reach, and the latter occurred even after closing and reopening the score. Quiting MuseScore fixed the tracking of the first slur but not the second. Will try some other tests.

      Bow_Tracker_plugin_06_TEST.mscz

We're getting there. Nice work!

scorster

In reply to by scorster

• I think that auto-update on selection change is possible in plugins.
• The symbols are only for debugging but could be changed to bowing symbols, (as articulations or as staff texts?), if it's worth keeping this option at all. I'm not sure what could make "add" any clearer: maybe a tool tip.
• The only way to keep it on top is by making a dockable version. I could make the dockable version have no controls and build the map automatically on run. This would give a very clean UI.

I'll test your score but I may well need a replication path to investigate the issue.

In reply to by yonah_ag

@ yonah_ag,

Thanks for you comments in your last post. I'm particularly excited about the possibility of the Bow Direction plugin auto updating as the user changes the note selection. If attainable, THAT will be slick!

yonah_ag wrote I'll test your score but I may well need a replication path to investigate the issue.

Here are steps that reliably replicate the error I encounter:

     • open the score attached in my previous post
     • clear the text marks that indicate bow direction on my last run
     • open the Bow Direction plugin
     • press the Map button
     • press the Add button

Problem: The stroke direction of the note after the second slur should be down (d), but it's marked u

Bow_Tracker_plugin_06_TEST u bow error.png

In reply to by scorster

Updating on change is actually easy using onScoreStateChanged but switching it off is tricky. Recursion also has to get dealt with since the plugin can make score changes, (adding d,u,r), which triggers another onScoreStateChanged!

See https://musescore.org/en/node/364953
and https://musescore.org/en/node/320673#s43

Even after a plugin is closed its onScoreStateChanged continues to fire, presumably because the plugin engine is always running as a background process.

In reply to by yonah_ag

Excellent!

onChange was likely overkill and, as you mentioned, led to recursion issues.

OnClick works perfectly in 0.6.2! And surely, that's adequate.

But is there a way to listen for Left and Right arrow keys and after keyPress or keyUp report the bow direction of the current selection? OH! It already works!! I didn't notice because I was arrowing within a slur.

That made me think: Each time the selection changes perhaps a little feedback in (or near) the direction rect—such as a flash or highlight—would visually assure the user that the displayed bow direction is unique to the sounded/selected note. Inherently we already have that adequate feedback when the bow direction changes, so perhaps the extra feedback should apply only when arrowing through notes within a slur.

Docking is nice.

Have you decided if the Plugin will open docked or undocked?

Once again, nice work!!

scorster

In reply to by scorster

OK, I was too loose with my terminology: the trigger that I can detect is onScoreStateChanged. This fires whrn a user changes the state with any action, (including clicking somewhere on the score), or when a plugin changes the state, (so it triggers on adding symbols to the score). Worse still this event continues to trigger after the plugin is closed. On re-opening the plugin there appear to be 2 instances of the plugin running, with both of them reacting to onSSC and implementing its processing.

The workaround is not exactly friendly!
https://musescore.org/en/node/320673#s43

In practise I'm hoping that it will not affect MS performance noticeably.

Maybe the bow symbol could be cleared in the UI for a fraction of a second before setting the new bow symbol. This might give some feedback.

The main issue now is clearly the faulty slur algorithm. It's a fundamental flaw in the logic so I need to rethink more carefully.

The docked plugin seems to work well even when undocked so I'll keep it. (I seem to recall that dock mode didn't work well with TAB Ring but I can't remember why.)

In reply to by elsewhere

Not necessarily. I would generally expect to perform a descending arpeggio with bow up and an ascending arpeggio with bow down. (Lower notes are in the "up" direction and higher notes in the "down" direction.) But not always; I've done both in either direction depending on context.

In reply to by yonah_ag

0.6.7 Hopefully this fixes it!

The plugin should only be run once in any MuseScore session. Even if you close the plugin it keeps on running, so opening it again actually causes 2 instances of the score state change to trigger. Every time you close and re-open, another instance of the trigger fires each time a note is clicked. Eventually this causes the plugin to slow down. There does not appear to be a fix for this, (see https://musescore.org/en/node/364953), apart from closing MuseScore and re-opening.

I couldn't find a way to briefly turn the symbol off before showing the next clicked note's symbol, (thus confirming that a change in note has been detected), so I toggle its colour instead. The two colours are defined near the top of the plugin via the cTog property.

Bowing 0.6.7.qml

Plugin Update 0.7.0 - Detect score closed

If the score is closed then the map is no longer valid so disable all buttons except for Map.

Bowing 0.7.0.qml

Note: The plugin requires MS3.6.2 or MS3.7.0 as there are hard-coded values to avoid using the very slow SymID enum.

In reply to by yonah_ag

A couple of points:
1. In the latest version the bow symbols appear too low (halfway out the box). I run 3.6.2 from the plugin creator.
2. onScoreStateChanged is not that reliable. If (after map) I click anywhere in the score I get 2 state.selectionChanged calls which trigger an unneeded noteBow. May not matter, but might be wise to check if the selection has really changed.
EDIT: Look at the code example in
https://musescore.github.io/MuseScore_PluginAPI_Docs/plugins/html/class…
‘onScoreStateChanged’ is really a misnomer unless the score feels ‘hurt’ after a mouseclick

In reply to by elsewhere

re: 1. In the latest version the bow symbols appear too low (halfway out the box).

I haven't encountered "out of box" bow symbols. Here in MS3.7 on MacOS the bow symbols are nicely centered in their container.

... However, when the user increases the height of docked plugin, the bow direction display and buttons grow increasingly distant from each other due to the object layout constraint properties.

And the Add button moves rightward when there's an increase in the plugin/palette width.

In reply to by elsewhere

Update 0.7.2

  1. Changed layout to fixed position, no reflow on size changes to the window. Works docked and undocked and I cannot get symbols to appear out of the box.

  2. Re-engineered noteBow to minimize code when not selecting a single note element. onScoreStateChanged is a bit flaky: you get a trigger on mousedown and then again on mouseup without changing the score in any way. It's the only trigger we have to work with so we just have to make do.

    bowing1.png
    bowing2.png
    Bowing 0.7.2.qml

Okay, I've just been testing it, and I got this. Kind of odd.
Screenshot 2024-07-06 at 2.02.35 PM.png
Maybe I'm doing something wrong, but it seems to be misinterpreting a few slurs. Other than that, this is amazing!

In reply to by scorster

I see HamSandwich hit the buzzer 4 seconds before me!

BTW, sometimes the "tracker" plugin provides perfect results on a score. Other times it appears to process no slurs at all—even on reopening MuseScore ... and reopening the score and running the plugin anew.

I've not been able to identify the trigger.

In reply to by Asher S.

The issue is being caused by the other 3 staves in your score. If I remove these then I get the correct result:

bowstave.png

I now have a replication path to work with. I already ignore these staves in the main mapping process but I'm guessing that they must be affecting the musicxml file which I have to generate in order to process slurs.

Update 0.7.4 : Fix for MusicXML with linked TAB (with or without slurs)

TAB with a bowing instrument?
Well, some scorers use this so it is another banana skin to avoid in the MusicXML. The TAB in a MusicXML file is mixed measure-by-measure with the standard notation so hopefully this fix does not slow down mapping noticeably on larger scores.

The fix works by removing backup sections from the MusicXML.

Bowing 0.7.4.qml

In reply to by yonah_ag

0.7.4 rocks! It no longer "ignores" slurs due to the presence of other staves. (Wondering, was it only linked staves that caused the issue? Not unlinked staves?)

This thing is fun to use. Takes a lot of tedium out of proofreading bow direction! And it helped me realize that I needed an up bow mark on a score I thought was finished.

Thanks so much for all your work on the project. This plugin goes in my workflow toolkit!

I would say too, regarding inferences: If a measure contains a rest before a single note "pickup" or a multi-note pickup, one can determine the pickup's starting bow direction by "looking backwards" from the first note of the subsequent measure.

Fortunately scor(ster)ists can add an explicit up stroke or down stroke articulation and make it invisible so there's no added bow direction articulation seen in the printed score. Thus the plugin doesn't have to rely on inferences.

Given the obstacles, i.e. the lack of plugin API exposures, it's quite impressive that you've tackled this. AND that you got this far so quickly!

KUDOS!! And thank you again.

scorster

In reply to by scorster

Re: Wondering, was it only linked staves that caused the issue? Not unlinked staves?

It was both unlinked staves and linked TAB staves but they needed different fixes in the MusicXML.

(1) Unlinked staves generate separate parts with each part being a contiguous block of xml tags. The plugin's regex processing finds the end of the of the first part and deletes all further tags.

(2) Linked TAB scores are completely different as the TAB notes are mixed in with the standard notes rather than being a separate part. Measure 1 of standard notation comes first, followed by the same measure but in TAB; then measure 2 of standard is seen, followed by measure 2 in TAB - and so on, alternating through the part.

This apparently simple plugin turned out to be much trickier than expected. If I started this project over again I would do the whole mapping in a single pass of the MusicXML instead of making 2 partial maps and then knitting them together. Such is hindsight but it's been an interesting learning experience.

I'll wait a couple of days in case any other issues surface before releasing v1.0.

In reply to by scorster

I recommended flashing or highlighting the bow direction symbol when the tracker shows succesive “same bow directions” within a slur. You opted to switch color with every stroke. This means that a down bow or up bow could alternate colors. Unfortunately this has the Stroop Effect on me (explained below.)

Wondering if you can assign a single color or all Down strokes and a single color for all Up strokes.

So then, on showing successive notes within a slur, possibly do one of the following:

• briefly show no stroke symbol, then show the current stroke symbol
• briefly show the stroke symbol at the same color as the background
• briefly show the stroke symbol with opacity (alpha transparency) = 0%
 

The Stroop Effect

The Stroop Effect (aka Stroop Test or Stroop Task) uses two basic challenges to illustrate conginitive interference.

When presented with an image like this:

     Stroop Test.png
... the person taking the test is to:

         a) go through the list naming the color of the font (i.e not say the written word)

          — or —

         b) go through the list saying the written word (i.e. not say the color of the word)

In reply to by scorster

Reminds me of the Brain Training game on Nintendo DS.

I can use any colours for any up or down but I haven't found a javascriot option for briefly show within a QML plugin. There is no sleep statement in javascript. I tried the suggestions here: https://stackoverflow.com/questions/951021/what-is-the-javascript-versi… but without success. If you have some code that works then I will incorporate it.

This is the only reason that I am using any colour at all.

In reply to by yonah_ag

yonah_ag wrote: I can use any colours for any up or down but I haven't found a javascript option for briefly show within a QML plugin.

Thanks. I remembered there was a rub, but couldn't recall what it was. ("No sleep" is hard on everyone!)

Now that the plugin works with additional staves present, just a single color per stroke type would suit me better. But I guess it's smart to wait and consider input from other users on that point.

In reply to by yonah_ag

And then there’s voltas.

It appears that the plugin determines the initial bow direction of the 2nd ending based on the final note of the 1st ending.

But a 2nd ending should calculate it’s initial bow direction by examining the measure preceding the 1st ending—that is, the 2nd ending’s start direction will be opposite of the direction of the final note of the measure before the 1st ending. This would hold true for other endings too.

scorster

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