Tempo Changes plugin improvement

• May 17, 2019 - 18:47

I've created a version of the Tempo Change plugin that gives some new power, so to speak (the changes are very small). The extant plugin provides a linear staging of the tempo difference, let's call that x, which varies from 0 to 1 over the interval (then multiplied by the tempo difference).

My change allows any real power of x. I find that 2.5 gives an effect quite more pleasing than the current 1.0. Don't laugh until you've tried it (you can make such a change without the UI in one line after studying the code). You might want different values at different times (I have a dialog slot), or start the deceleration at different points back (in conjunction with finding the best exponent).

Sample of 2.5 (at both double-bars in the first (I) and last (V) canons): https://musescore.com/bsg/scores/5571862 .

Then answer as to whether or not this is useful.


In reply to by Shoichi

Inserting these two lines
var x = (cursor.tick - sel.start) / durationTicks;
var newTempo = (x**2.5) * tempoRange + startTempo;
in place of
var newTempo = ((cursor.tick - sel.start) / durationTicks * tempoRange) + startTempo;
in TempoChanges.qml are all you need (2.5 or whatever) to experiment with it yourself. The original line is misparenthesized (but not buggy) anyway.

Essay question: is this a change that the current maintainer should integrate, or a conceptually new bizarre feature? I.e., is it so bizarre and hard to understand that it would lessen rather than enhance the value of the current plugin?

I really need guidance on this (new "nonlinear tempo change plugin" or change existent plugin source (how would one do that?)). Is there a place/API where a plugin can store/restore parameters (e.g., I would far prefer quarter=60 rather than 120 as a default start-tempo).

Let's see if I can include my work as an attachment (a form of cheating, but this might help evaluate it). Ah, it liked it! So download away and have fun....

Attachment Size
BSGTempo.qml 12.57 KB

It is worth noting that was unable (by request) to make this work in MuseScore 2 because the version of QtScript/Javascript used there does not support the ** (exponentiation) operator, nor the function "exp" (but "log" is there), nor does the QtMath package seem accessible. That's actually a pretty severe set of flaws, but MS 2 can't really be an issue. Much more pressing is the problem of why I can't load the "standard" Tempo Change plugin in to MS 3.1!

In reply to by BSG

Hi, do you have a github account? If so, I'd welcome your changes to be integrated together with the pending PR from billhails.

Note that for the maths part, no Qt stuff should be required, but the default JavaScript maths should suffice (in this case Math.pow(base, exponent) should work)

In reply to by jeetee

Hi, we should talk about this. The MS3 version uses "**", and works perfectly. Should we worry about MS2? Let me try Math.pow for my MS2 version. I do not have a GitHub account, and am not ready to get one. What is the PR from billhalls? (The note graphics other than quarter note are broken. Is that it?)

You think a fill-in box labelled "Exponent" is not too confusing for users who can't imagine what it is? I assume the default should be 1.0 (e.g., act as now). You should just pick up the changes I posted here, and change the default from 2.5 to 1 and ignore my changes to the description/header.

How shall we document this? A graph like this included should be included.

In reply to by BSG

His changes also add exponential as an input, with a slider that lets you set the midpoint of the curve.
It can be found at https://github.com/jeetee/MuseScore_TempoChanges/pull/11

I've plotted your exponent of 2.5 (curve 7) against his implementation, and you can notice you're quite close into the 75% curve (curve 3): https://www.desmos.com/calculator/lymxbfdizn

I'm currently working on changing the plugin layout to display that curve as a graph, with the slider underneath it. I'm wondering whether adding other curve types (quadratic?) would make sense as well.

In reply to by BSG

From the comment in his patch:

        // input is the current fraction of the number of ticks in the range 0.0 - 1.0
        // The early/late linearity slider also ranges from 0.0 to 1.0 (or could do, but we limit it to .25 - .75)
        // * With the slider at 0 we would like all of the tempo change to be applied immediately.
        // * With the slider at at 1/4 we would like the mid tempo to be reached 1/4 of the way through the change.
        // * With the slider at at 1/2 we would like the mid tempo to be reached 1/2 way through the change, etc.
        // Put another way:
        // * When the input equals 0 we want the output to be 0.
        // * When the input equals the slider value we want the output to be 1/2.
        // * When the input equals 1 we want the output to be 1.
        // We can do this by raising the input to some power p, because for any p
        // 0^p = 0 and 1^p = 1, and so we only need calculate p for the current slider
        // value, where we know the result should be 1/2.
        // What power p do we need to raise the current slider value x to, in order to equal 1/2?
        // x^p      = 1/2
        // log(x^p) = log(1/2)
        // p log(x) = log(1/2)
        //            log(1/2)
        // p        = --------
        //             log(x)

In reply to by jeetee

Yeah, I had just found it. This is superlative (although I think the 75% limit is bad -- unreasonable settings will produce unreasonable results, not harm men, women, and children). He's gone the whole way, and I wish I had known about this. Ignore my weak approximation to this masterpiece, and let's get this working under MS3. Documentation is still tricky. What has to be done to make this work in 3, just import-file version #changes?

In reply to by BSG

@jeetee, Quadratic is just "exponent = 2" (in my formalism), .5*log(.5), i.e., 70.7% (sqrt(1/2)) within the slider in his. I tried e**x (scaled), which is *not* handled in either formalism, and it fell between 1.0 and 1.5 in a way that didn't seem to add any power (as it were).

I tried Bill's plugin. The effect is wonderful, but the implementation is deficient insofar as there is no numeric indication of the value you set in the slider, so you cannot tell it to someone else, or reproduce or conceptualize it on a subsequent use (save/restore value is another direction for improvement). It clearly needs a visual % field reflecting the slider, or even markings on it. Does billhall have an account on this site where I can contact him?

@BSG... I just came across this post.

You wrote:
I find that 2.5 gives an effect quite more pleasing than the current 1.0.

So, for a 2.5 ritardando, you arrive at half the initial BPM value later (in time) than for a 1.0 ritardando. Yes?
Using your graph screenshot (as I, too, don't understand those other curves):
I hope the axes are labelled correctly.
P.S. (I also realize that jeetee and billhails are working on this.)

In reply to by Jm6stringer

That's exactly right! You must understand my graph if you so labelled it. The billhails plugin, now in jeetee's version in progress, lets you move the half-way point along that middle axis you drew. Measuring time from 0 to 1, it gives you that*100 (i.e., percent). My 2.5 is his 75%, as is very clear from your enhancement of my drawing! I assume you listened to my new little score that uses 2.5 ritardandi.

In reply to by BSG

I just wanted to be crystal clear about this function, and so I enhanced and labelled your graph.

Jeetee's use of the midpoint as the adjustable parameter (in his illustration) seems simple enough (if a user has a clear understanding of its function - whether pondering the BPM midpoint or, by logical extension, where the BPM change gets 'bunched up' ).

It truly will be an elegant and sophisticated playback feature.

In reply to by Jm6stringer

Your enhancement of my graph is crystal-clear. As I've said a couple of times already, documenting this so that its ease of use surpasses its seeming obscurity, in an age when no one even reads documentation, is going to be a challenge. It really involves the third derivative of position, i.e., how the acceleration/deceleration behaves.

In reply to by BSG

An interesting fact is that that graph is still extremely relevant to understanding the effect of jeetee's plugin, although labelling the curves with their generating exponent would no longer be useful (except to those with math backgrounds wanting to understand its means).

In reply to by BSG

An interesting fact is that that graph is still extremely relevant to understanding the effect of jeetee's plugin...

Indeed, as presently, only the graph's curve #1 - that is, the strict linear change of BPM over time - is used by MuseScore.

(BTW: Your nonlinear ritardandi al potenzà due e mezzo has quite an effect.)

In reply to by jeetee

Here are my observations on the preview:
Note-value dropdown shows squares with question marks (still),
Notes barely visible in dark mode, but I don’t know what you can do about that.
At first I thought the graph wasn't there, but it's just very dark (purple) in dark mode - s/b white etc.
Does qml even know it's in dark mode?

Spinner increments are 1.0, not 0.1 as you said.

“Linear” vs “Exponential” is not quite right; the opposite of “linear” is “custom”, “custom power’? Maybe you should add “Quadratic” (expt=2, = 70.7% (sqrt(.5)), as well, so it is clear what is being adjusted/customized.

If the dropdown is “linear”, the slider and spinner should say “50%”, no?

In reply to by BSG

Note-value dropdown shows squares with question marks (still)
Nothing was done on that front. It seems to be a Qt/Mac only issue: See also https://musescore.org/en/node/283404#comment-912984

Dark mode
Currently the plugin isn't aware yet, but I'll add that. Then perform some explicit styling on the dropdown and change the line color of the graph to something brighter when in Dark mode.

Spinner increments are 1.0, not 0.1 as you said.
Noted, will fix that

“Exponential” is not quite right
Correct, not sure which term would be better. Technically it's a special case of "Monomial" allowing non-integer exponents, but I doubt this means anything to a musician.
Perhaps "Linear/Curved" suffices?

If the dropdown is “linear”, the slider and spinner should say “50%”, no?
It could; currently both get disabled when you select Linear; but for the slider that's stylistic apparently totally unnoticeable.. The reason for possibly not doing so is to keep and (re)store the % easier when you switch back to "Curved" mode.

In reply to by jeetee

If "monomial" means nothing to a musician, so does "exponential". Shaped, custom, controlled, nonlinear ("linear" is there already). i understand the problem with .5; maybe the slider should be hidden when in "linear"? Let's keep thinking about the name. Note that in dark mode, the color of the "note" should change, too.

Maybe the broken menu with the notes should have words ("dotted quarter"), too, until fixed. Not otherwise usable on the mac unless you try them all.

In reply to by jeetee

Thank you for these response - eagerly looking forward.

Here's a somewhat related question. I'm a career programmer with very substantial skills, but I find programming in the extension environment onerous -- no breakpoints/eval, no search in editor, no clear documentation of the language (js/qml/ms boundaries) -- do you have any tips or tool recommendation?

Attached is a 10-line python program I have and have found useful to convert back and forth between half-%'s and exponents (the single argument is a number, which, if > 10 is the former, else the latter) (rename from ,txt).

Attachment Size
p2v.py.txt 306 bytes

In reply to by BSG

What is the status of this work? I'm very happy using your "sneak preview", but it'd be cool if others had it, too; it seems so close to "done"... save/restore settings would be great, but it could live without it. I'd be happy to help contribute to the documentation.

In reply to by BSG

Sorry for the radio silence.
Currently dealing with the recordings of a choir concert from last Saturday. I expect to pick this up again over the weekend and will release "as is" by the 9th of June if I can't polish it before then.

In reply to by BSG

Ah well.. who listens to the French anyway ;-)

Kidding aside, v3.1.0 has been officially released now. Updated the plugin page here on MuseScore with some new screenshots as well.

With regards to theming: whilst the plugin could access the MuseScore theme style property, it is unable to further access the value within the property at this point within the plugin framework.
Instead I've chosen to manually (and fixed) style the graph to something that probably looks best in place in the dark theme, but doesn't screw with you in the light theme either. Similarly, I've forced the slider style as well, which did allow me to better distinguish it's enabled/disabled state.
For the beat duration dropdown, I've forced the text color to black, to make it at least readable in the dark skin as well.

The plugin should now also remember it's linear/curve preference as well as the midpoint value associated with the curved option.

It has not yet been ported to v2.x

In reply to by jeetee

This is pretty terrific. I'll try it out and evangelize it, as they say. While the description is good, I think it should at least have something of an attempt at a technical explanation. First draft: The tempi are accelerated or decelerated according to a power curve of variable exponent; when the slider is at 50%, the exponent is 1.0, i.e., the tempo change is linear. This is similar to algorithms employed in other score editors.

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