Can a plugin access on-time/off-time?

• Jun 27, 2019 - 16:08

I.e., if I grit my teeth and dose up on coffee, can I write a plugin to impart a desired phrasing upon a run of notes?


Comments

In reply to by BSG

It's just been an underloved part of MuseScore in v2.
The internal changes of v3 broke a lot of things internally, including nearly the (very limited) complete plugin framework. Slowly dmitrio95 is, with the help from some contributors, re-enabling the v2 stuff and newer properties.

As far as I'm aware there is nothing blocking pretty much full exposure of all functionality and properties besides someone having to put in the time to do so.

In reply to by jeetee

If we could have off-time exposed, the extant ability to select all the notes in a voice in a staff, or within a selection so narrowed, would allow the instant re-articulation of whole instruments, passages, runs, etc., and with a little more plugin-UI, pairs/triplets etc. What a boon that would be to every musician using this program!

In reply to by DLLarson

Well, I guess I had to trim my beard, but....

of "Note:", setOnTimeOffset(int), setOffTimeOffset(int) at bare minimum, but there are no corresponding accessors to retrieve the int value, and it'd be nice to have (one should be able to get what one wishes to set). I don't know if setOffTimeType(int) and setOnTimeType(int) are needed --- the header file note.h says that it's compatibility (1=user, 2=offfset%) obsolete)? Do you know?, but, oddly, there are accessors for them, int offTimeType(), int onTimeType(). % probably means per mille, I'd bet.

Thanks!

In reply to by BSG

Hi,

>Well, I guess I had to trim my beard, but....

The actually took a moment to sink in! Well it's probably good to see what's under there on occasion.

I have the onTimeOffset and offTimeOffset values exposed in QML now.

With regard to the offTimeType and onTimeType, I don't see those values used anywhere in the code except for what looks like file load code:

https://github.com/DLLarson/MuseScore/blob/master/libmscore/read114.cpp…

This might be for loading (and saving?) v1.1.4 file formats but I'm not near familiar enough with the overall program to know.

I don't think it'll be useful exposing those values.

I tested this by doing simple sets and gets in a QML script and all seems well.

        console.log("Before: note.onTimeOffset=" + note.onTimeOffset)
        console.log("Before: note.offTimeOffset=" + note.offTimeOffset)
        note.onTimeOffset = 100
        note.offTimeOffset = 990
        console.log("After: note.onTimeOffset=" + note.onTimeOffset)
        console.log("After: note.offTimeOffset=" + note.offTimeOffset)

On Console:
Debug: Before: note.onTimeOffset=0
Debug: Before: note.offTimeOffset=1000
Debug: After: note.onTimeOffset=100
Debug: After: note.offTimeOffset=990

That really doesn't mean much though. Is there a way I can get you a test version MuseScore3 test to see if it's really as useful as you hoped. I'm not really affiliated with the MuseScore organization.

For now my changes are on my fork of MuseScore here:

https://github.com/DLLarson/MuseScore/tree/add-onoff-time-props

Oh, I'm running on Windows if that matters.

-Dale

In reply to by DLLarson

This is great! I'm running Mac, so a Windows build will not help me (nor am I willing to set up and debug the build environment).

The most apparent tests would be (1) interaction with the piano roll editor -- if you can grab a note in the plugin, set its off-time to 500, and look at it in the piano roll editor and see if it's indeed been halved , and see if the plugin sees changes made in the PRE, and (2) see that plugin-offtime-modified notes indeed play that way, e.g., 500 off-time = staccato.

In reply to by BSG

You have to know what a note whose "length"/off-time has been adjusted sounds like. That's the point of my need. Enter some notes on a non-percussive instrument (e.g., violin, oboe, but not piano or harp), listen to how it sounds on playback, go into the PRE and change the lengths to 500 or 700 and listen again. If you can make a plugin that makes that change, we are set.

In reply to by BSG

The script changes are indeed reflected in the piano roll.

Here's the test score. (The comment about undo's is addressed later in this post.)

PianoRollTestScore.png

The script:

        // :
        console.log(noteNum + ": Before note.onTimeOffset=" + note.onTimeOffset)
        console.log(noteNum + ": Before note.offTimeOffset=" + note.offTimeOffset)
        if (noteNum == 0) {
           note.onTimeOffset = 250
           note.offTimeOffset = 750
        } else if (noteNum == 1) {
           note.onTimeOffset = 0
           note.offTimeOffset = 500
        }
        console.log(noteNum + ": After note.onTimeOffset=" + note.onTimeOffset)
        console.log(noteNum + ": After note.offTimeOffset=" + note.offTimeOffset)
        noteNum++
        // :

The result:

Debug: Found a Chord
Debug: 0: Before note.onTimeOffset=0
Debug: 0: Before note.offTimeOffset=1000
Debug: 0: After note.onTimeOffset=250
Debug: 0: After note.offTimeOffset=750
Debug: Found a Chord
Debug: 1: Before note.onTimeOffset=0
Debug: 1: Before note.offTimeOffset=1000
Debug: 1: After note.onTimeOffset=0
Debug: 1: After note.offTimeOffset=500

PianoRollChangedByQML.png

However, note that the undo facility doesn't recognize the change so you can't easily back it out.

It also appears that the piano roll editor may have an undo stack that is different from the main program.

I raise this concern because I ported forward some v2.0 properties to 3.0 and the "setX" operations were rejected during the commit review for this very reason. I fear the same outcome may result in this case as well. The undo problem will need to be solved.

https://github.com/musescore/MuseScore/pull/5162

The undo system seems almost mystical to me since I don't see an undo layer everything passes through (it must be there somewhere.)

-Dale

In reply to by DLLarson

You don't have the whole PRE frame there -- did the changes show up properly in the "OnTime" and "Length" slots that are cut off in that image? How do the Inspector changes to Velocity get undo-stacked? I know that the changes made by the TempoChange plugin can be Undo-ne.....

In reply to by mike320

I'm not sure where this belongs. Seems to be it should be in the C++ code. I did add the calls to my test QML like so:

        console.log(noteNum + ": Before note.onTimeOffset=" + note.onTimeOffset)
        console.log(noteNum + ": Before note.offTimeOffset=" + note.offTimeOffset)
        if (noteNum == 0) {
           curScore.startCmd();
           note.onTimeOffset = 250
           note.offTimeOffset = 750
           curScore.endCmd();
        } else if (noteNum == 1) {
           curScore.startCmd();
           note.onTimeOffset = 0
           note.offTimeOffset = 500
           curScore.endCmd();
        }
        console.log(noteNum + ": After note.onTimeOffset=" + note.onTimeOffset)
        console.log(noteNum + ": After note.offTimeOffset=" + note.offTimeOffset)

and ran the plugin (in the plugin creator) but neither of the undo buttons (main app or piano roll editor) reflected the change.

-Dale

In reply to by DLLarson

In the plugin api C++ code...

  /**
   * For "dock" type plugins: to be used before score
   * modifications to make them undoable.
   * Starts an undoable command. Must be accompanied by
   * a corresponding endCmd() call. Should be used at
   * least once by "dock" type plugins in case they
   * modify the score.
   */
  Q_INVOKABLE void startCmd() { score()->startCmd(); }
  /**
   * For "dock" type plugins: to be used after score
   * modifications to make them undoable.
   * Ends an undoable command. Should be used at least
   * once by "dock" type plugins in case they modify
   * the score.
   * \param rollback If true, reverts all the changes
   * made since the last startCmd() invocation.
   */
  Q_INVOKABLE void endCmd(bool rollback = false) { score()->endCmd(rollback); }

Whatever dock type plugins are. I don't think my test QML is one of those.

-Dale

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