Piano Roll Editor inconsistency/confusion.

• Aug 3, 2019 - 18:57

(I'm afraid I might get elected Prince (or dogcatcher) of Piano Roll Editors....)

Create a quarter-note tied to another, over the barline or not.

Go into PRE, and click on the FIRST PART of the note. Set a "len" of 500‰. The upper part of the note will be 500'ded, visibly (in PRE) and audibly (play it back from PRE). While there is a great deal of utility to this interpretation, you "have to know about it". As a matter of fact, even 0 will only blow away the upper portion of the .... what do you call it, "note-complex"?

It shouldn't even really be accepting, or (falsely) reporting len's of non-final-portions of notes.

What I still don't understand is why, when I cut the upper portion from the QML API, it plays correctly, and tells me back (via QML) what I put there, but the PRE still shows 1000 len (and yellow-bar length), although playing what I want it to. I wonder if it cached things thinking that it is the only author of on/off times....


Comments

Just out of curiosity:
After you've done this, have you tried to turn off the piano roll, play once, then turn it back on?
Is everything still the same?

Just a prediction from my previous experience (perhaps from the 2.x version).

Edit: And there was always a problem with the combined notes. (The problem that makes it look like a single note). Although you could edit both on the score separately, it wasn't on the piano roll.

In reply to by BSG

If I use the PRE to cut back the second part to 500, then inspect the off-times from QML, the FIRST part shows as 500, and the second as 1000, the exact opposite of what we hear. In the PRE, both parts report "500". The yellow bars show the second part cut 50%, and that is how it plays. The PRE is putting up the illusion of one note (doesn't matter where you click on it), but what it means is to modify the last component. At very least, QML has to learn about tied note. It is fortuitous and surprising that adjusting the last component via QML works at all.

In reply to by BSG

Eh, if you have two tied quarter notes, then set the combined length to 500‰, then I’d expect to hear one quarter (i.e. first note 1000‰ second note 0‰). No idea how I’d expect that to be recorded in the MSCX, but that can stay/be implementation detail, but the PRE ought to show a tied note as one only.

In reply to by mirabilos

It does not work that way today. You can try it. The params of the last note are recorded in the mscx as those of the first note, and neither is the "combined note". Don't believe me, try it and see.

The bigger problem right now is that the new plugins, which have already produced terrific results, do this "wrong", (try to adjust the last note, and that's what you get) but MS somehow "likes it", but may not always.

This is chaos. Look at the enclosed tiny nMSCX and open it ; it was written by MuseScore, not hacked by QML, but I used the PRE directed at the FIRST note component to "cut it to 500". Stunningly, it cut the third (of three), as we've been observing, and the PRE showed that, 3rd cut, played that, but the MSCX has an explicit cut note event for the FIRST event!....

Attachment Size
ttnew.mscx 5.3 KB

In reply to by BSG

I tried (and succeeded) to reproduce that from QML. I created three notes, just like above, and directed QML to cut the first one to 500. And, sure enough, the same inconsistency: the third is audibly cut; QML sees 500, 1000, 1000. Piano Roll editor shows 1000, 1000, 500 (i.e., a 2500 long bar), which is what we hear. XML sees 500, none, none.

So the rule must be, "You can only adjust the last component of a multi-note, but you must do so by adjusting the first with data about the last; the number you supply applies to the last component, not the whole, or the first, or any other". The piano roll editor won't let you do anything else. It should be that QML doesn't let you, either, or maybe the API; the inconsistent stuff we create via QML is a time-bomb, but it plays, edits, writes out, and reads back 100% "correctly". All it doesn't do correctly is piano-roll edit. And this odd dance has to be part of the PRE documentation; you can't use accurately it without knowing this.

In reply to by BSG

I have looked at the data structure with the debugger window in the Debug build, and, unsurprisingly it reflects the MSCX/XML state of affairs: The notes that play 1000,1000,X bear NoteEvents with offtimes X, 1000, 1000.

I imagine that it is not an accident that adjusting the last note's note events works. Maybe something else depends upon this, in which case, the PRE's non-recognition of it is a bug. Anyone else have any expertise in these woods? At the worst, I'd have to retract my whole technology, and take down all the scores posted with it, from public view until it does this consistently! That would be .... well ... not so great.

In reply to by BSG

Perhaps this was mentioned already but I noticed that in the score only the first note has any Event associated with it. The follow-ons have no event info. It's as if the file format assumes the first note speaks for all the tied notes.

I think what's happening on file load is that, when an Ms::Note is created, the constructor always preloads it with a single NoteEvent having start=0, len=1000 so you get a backwards looking construction when dumping PlayEvents using QML note by note. From the C++ code:

Note::Note(Score* s)
   : Element(s, ElementFlag::MOVABLE)
      {
      _playEvents.append(NoteEvent());    // add default play event
      _cachedNoteheadSym = SymId::noSym;
      _cachedSymNull = SymId::noSym;
      }

So is this tied arrangement supposed to be at least two 1/4 notes long PLUS 500 for the 3rd note? Or is it supposed to be just 500 long starting at the first note so that a len range of 3000 may be needed to extend the whole set of ties? I'm asking dumb questions as I'm not a music/synth subject matter expert.

-Dale

In reply to by DLLarson

The intent is exactly what you hear in all cases, effectively 2500 long. I don't want to change the representation, I'm completely happy with only being able to adjust the last component, which is all the PRE allows you now.

Let us put the PRE/UI issue aside for one more urgent. The XML, and the code say that "the first note speaks for the last note, at some level, the whole, but only the last can be adjusted." The problem is that the QML is unaware of this protocol; QML has no access to tie information, and is modifying tie-chain-non-first notes if that's what you ask for; that'd be the first thing we could do stop this bleeding (creating nonstandard files). It's pretty straightforward from the Debugger, but QML has to be aware of it. (QML can create bad files now -- try putting ampersand-foobar in a staffText and the MSCX will not be able to be read). But the "nonstandard files" we create now are "not so bad" as to not "work". QML has to know about ties, so it can at least try to do this right.

A more complex but more robust solution might be to redirect requests/sets for "playEvents" array of a non-first tied note to that of the first at the C++ interface level.

At any rate, I'm now concerned about spreading brokenness in an already ailing world ....

In reply to by BSG

>QML has no access to tie information, and is modifying tie-chain-non-first notes if that's what you ask for; that'd be the first thing we could do stop this bleeding (creating nonstandard files).<

Actually you do have access to that info. From the tin-whistle-tab.qml:

           if (cursor.element.notes[0].tieBack == null) {  // don't add tab if note is tied to previous note
              // there are no chords when playing the tin whistle, so use first note
              var chord = cursor.element;
              var pitch = chord.notes[0].pitch;
              text.text = selectTinTabCharacter(pitch, basePitch)

That part is not my code but I assume it works.

-Dale

In reply to by DLLarson

Are the note-components of the tie-back accessible? That would solve everything. Is there any way to get to the first note if you see that? It would be bad to say you can't adjust the last component from the score until you get to the first (i.e., spread this behavior into UX). Or if not, can we make it be?

In reply to by BSG

What I meant is I have no idea what all that Tie* stuff is why the api gives you first and last. It's too raw.

Looking deeper I find that the Plugin api docs created by Doxygen was showing me the api's for the INTERNAL Ms::Note object. My bad.

-Dale

In reply to by DLLarson

I understand what the API's are and why they're called that, but for now, other than note.tieBack, you say the're not there. Oughtta be there? Better than this?

MessageDialog {
id: tieBackError
visible: false
title: qsTr("Tie-back note error")
text: qsTr("Adjusting a tied-back note is difficult. Press 'Detail'");
detailedText: qsTr("In order to set the articulation parameters for a note " +
"which is other than the first note of a tie chain, you must " +
"set them for the first note (current MuseScore internal restriction.")
onAccepted: {
Qt.quit()
}
}

In reply to by BSG

I'm looking at the other Note based methods which would be easier to do since we already have a wrapper for Note.

Note.firstTiedNote
Note.lastTiedNote

I haven't had time to cut the code though to see how it works. The "Tie*" stuff would be much more complicated. It's not a simple object.

-Dale

In reply to by DLLarson

Those two would be fine, but I must know what they would return if the note isn't tied, and if I can do an address== check (or what) to know when I've gotten to the first of the chain. I suppose it might just give null first and non=null last. I can try it as soon as you can compile it (substitute a module).

In reply to by BSG

I tested it manually.
In the present case, only the values of the first note are valid, and values aren't correct.
for example: start and length values of two tied quarter notes aren't to same as of a half note.

The start and length values of other tied notes do not matter, they only serve to extend the note.
If you play with the values of the second (and third, fourth if any) notes, you may get unwanted results.
for example: the middle note may disappear from the piano-roll-editor. the length of the note (when play it, although it does not appear that way) may be shortened, etc.

In reply to by Ziya Mete Demircan

As I said, the start and length of the first note apply specifically to the last note. The start and length of the non-first note should not matter, but the last one can be used to affect playback as though it "worked properly". Do you see the same? There is no way to change the parameters of the non-first notes other than QML code (or .mscx editing).

In reply to by BSG

Create Two successive, adjacent quarter notes. In the PRE, cut the second one back to, say 500. Now Just tie the @#$#$ notes. BLAM! The exact same situation created by QML, including proper playback, QML visibility, and PRE ignorance. That's why the situation is supported, and can't be desupported. I am in good company (I and +) in leveraging it.

The bugs are 1) multiple, ill-defined param models for extended notes, 2) PRE ignorance of (1) 3) Ziya's case of removing a tie leaves chaos. My plugins are not buggy. MS and the PRE are,

Thank you Ziya!

In reply to by BSG

OK, the Ziya test catches the insanity by the neck: Enter two quarter notes; tie them. PRE cut "them" back 500, which actually mutilates the data structure of the first to cut back the second, Discard the tie, play, and laugh: the first will be cut back by its bogus data, and the second will play full.

"What we clearly mean here is not perfectly clear" as a program I once ran famously said. My plugins are the least insane thing here, and there is no need for more QML API until some redesign is attempted,

In reply to by BSG

I've been dealing with these since 2.x.
And when I want to do something in PRE, I can hardly get the result I want.
it works just on one (untied) note correctly.

Another problem is that when the start time increases, the length remains the same.
You need to subtract the start time from the length value and then apply the desired percentage value to the remaining length value.
Example: Let's say the start time is 150, 1000-150 = 850 (This value is the end of the full value note), Now let's give the gate time: 850 * .80 = 680. Very strenuous processes.

Instead, it is less tiring to define an articulation that we do not use at the time, such as marcato, staccatissimo, according to the approximate value we want in mscx. //Then make it all invisible.

Unfortunately, there aren't enough articulations to use this way.

And I give up constantly :)

In reply to by BSG

Another question is, "how would you 'fix' the PRE UX?" If there is a very odd chaining of notes, say, a whole to a quarter (over a barline) to a sixteenth, do you really want to apply articulation to the whole irregular thing? I think not. You may want to apply on-time to the beginning note, and off-time to the final note, based on those two far-separated contexts. So "two quarter notes, same as half!" is not close enough for my comfort.

In reply to by BSG

answer to "another question":
This is very complicated to solve with Musescore software.

According to my gate-time theory: Gate time is set by denominator, not by total length: //example: for 4/4;
gate-time based on quarter-note.
Or by metronome beat value (If it's different from denominator). //example: 80bpm for half-note = gate-time based on half note

examples (for 4/4):
For values ​​equal or smaller than quarter note, a selected (fixed) gate-time is applied. // note * gate-time.
For larger values than quarter-note, the remained last note of the length is taken into account (after modulus).

https://www.hedsound.com/p/gate-time-theory.html

Of course, while a human-player can do this automatically, even applying it to a simple piece of music with software takes a lot of time.

In reply to by BSG

Yeah, I just read it. congratulations.
Very detailed, long, beautiful;
Just before the Bach part, you lost me.
and after many more examples, I want to escape to an unknown planet in space //sorry for this :D

I think may be our approach is a bit primitive.
Perhaps a participant with a fresh eye and brain can find a better way.

Workaround: If four or five "user defined gate-time" values are defined (for per score), this may be a workaround for the problem, and PRE can be used for other minor adjustments temporarily. (Until PRE's problems are solved) .

For Legato, the MIDI concept uses a Mono-mode for this.
The software (synthesizer) simply does that: the first note is played normally; next notes (if not contain a gap) are played starting from the sustain section. // The attack and decay portion of the sample is automatically skipped by the synthesizer (the same goes for the glissando).

And all synthesizers (including fluid) can do this when apply two valid CC commands (mono-on, legato-on) and/or (mono-on, portamento-on).

Of course, the main task of a engraving software is to input and display notes.
But the playing part is just as important.

In reply to by BSG

Good idea.

and based of a denominator. // To make a simple thing even more complicated :)

d1.0 = quarter
d0.5 = eighth
d2.0 =half
etc.
using the "d" as a trigger


or an options menu (Whichever is convenient for the user.):

[select mode]
fractions   (1/1)
denominator (1.0)
thousandth  (1000 )

Though, none of this will happen, but it's good to dream.

In reply to by BSG

For happy people who don't want to deal with piano roll editors, simply create tied pairs and put the staccato dot (shift S) on first one in the first pair, then the other in the other pair, which will have the exact same effect as the PRE manipulations recommended. MuseScore will behave identically as described above. Staccato the first note, and the second will be cut 50%. Untie, and the first will sound cut, and the second restored. Staccato the second (of new pair), and it will behave correctly whether tied to the first or untied and retied. In fact, I have been using portato (same articulation abuse idea as Ziya has just discussed) for a long time on "end notes", producing the same varieties of internal confusion and files differing from PRE action; I didn't understand why I was getting what I was then (in every case exactly what I wanted), but now I do.

I would go so far as to say that the PRE displacement of the articulation parameters to the first note is the bug. When a tied note is PRE modified, it should find and put the parameters in the last note, and respect seeing them there. If you staccato-dot (etc) the first note of a chain, it should either reject the attempt, or do the same (modify the last note), but doing so (staccato etc) articulating the first note of a tie chain is a meaningless thing to do (although one can imagine it being called for, inactive, in the visuals of outré scores).

In reply to by BSG

As usual, Ziya is a few steps ahead of me. The entire per-mille of note system is bankrupt. Pun intended, that's the long and short of it. The idea that a given "articulation" tool can assigned a fixed per-mille is bankrupt (well, maybe it has a few euro in its account ...) A sixteenth note cut in half to make staccato, an eighth note, a quarter in cut time ... that often works passably. But if articulations be abused for, well, ... articulation (phrasing), 85% or 90% might work for the faster notes, but fails completely for longer notes (e.g., canti fermi in chorale-preludes), when "articulation abuse" phrasing must cede to the Piano Roll Editor (or both to the plugin). The whole per-mille system, per mille of note value, is intellectually bankrupt, and the currency should be, as Ziya says, "denominators". I should be able to cut back the start of simultaneous notes of different lengths the same amount with the same number!

Needless to say, "we have a problem" with extant scores were we to contemplate change, but a new per-score option, "What do you want articulation to be measured in? (a) 1/1000 of note (compatibility) (b) 1/1000 of quarter notes (c) ticks (d) 1/1000 of denominator unit etc. (new default)", compatibility could be had.

Bankrupt.

In reply to by BSG

PS: I was looking at what could be done without changing the current system ...

1st input box (start-time): no-change; same as current.

example for dotted half note (Assuming quarter note as denominator):

[quarter-(start time)] + quarter + [quarter*(gate-time)]

 
in thousandths:
say: start-time=15; gate time = 45%
1000/3 = 333 (denominator)

( ["start-time"- 333] + [333] + [333 * "gate-time" ] )
 
==> start-time: [15]
    len: [801]       //(318) + (333) + (150)

 
The user doesn't see this calculation.
So I added the (% remaining) portion of the gate time, as a simple input.

Edit: I just tried to see if changing the calculation system in the code might work. It may not be ideal.
Or ignore it at all :)
Suppose I speak to myself.

In reply to by BSG

Sorry, what I meant was: when we go to on-time and off-time instead of permille, maybe there should be a “reset to defaults” button for a note, to undo every PRE change. With permille, it’s easy (0 and 1000 are the defaults), but off-time depends on the length.

In reply to by mirabilos

The PRE currently has "on-time" and "length". Even with no (proposed) change to the meaning of the numbers, I think "on time"/"off time" far beats "on-time"/"length", as it should be possible to only adjust the on-time, and today it is not. It should be possible to change the off time from 1000 to 900 whether the on-time is zero or not. I have proposed that PRE UI change in an Issue months ago.

My issues are about "what the per-mille are per-mille OF". Indeed "reset to defaults" would become difficult.

In reply to by mirabilos

Other than the len=>off time fix, what is needed here is clear definition, and, vexingly, compatibility with extant scores. "Crazy", as a technical term, seems basically correct. I would have said that the situation is a mess of confusion, difficult to understand, explain, or work with, and near-impossible to justify. The PRE is trying to hide some of it, which is an approach. Again, verify my revelations with your own experiment.

I do not think it is easy to propose what it should be. It is inextricably wedded to the issue "per mille of what", because clipping equal things off the coincident starts or ends of notes ought be straightforward, whether they're quarter notes, half notes, or a tie-chain equal to the same.

In reply to by BSG

Sorry, not at the moment, I’m not very familiar with the source code either, and busy with both $dayjob and preparing for a conference… just trying to get stuff done today that shouldn’t wait for next week.

But I’ll forward the request to dev chat.

In reply to by BSG

I did some code spelunking and here's what I found...

When you select an item in the PRE the following function PianoView::addChord() is called to add the chord's notes to an internal PianoItem list.

https://github.com/musescore/MuseScore/blob/5979345eae6a768640b707584d2…

You can see that this code walks note.tie's back to the first note and uses that note in its PianoItem in later processing:

void PianoView::addChord(Chord* chrd, int voice)
      {
      for (Chord* c : chrd-&gt;graceNotes())
            addChord(c, voice);
      for (Note* note : chrd-&gt;notes()) {
            if (note-&gt;tieBack())
                  continue;    // Keeps going until a non-tied note is found.
            noteList.append(new PianoItem(note, this)); // Then adds that first note to the PianoItem
            }
      }

i.e., it always points to the first note in a set of tied notes. Later methods like PianorollEditor::tickLenChanged(int val) and PianorollEditor::onTimeChanged(int val) use this data to access the note to affect the PlayEvent timing.

https://github.com/musescore/MuseScore/blob/5979345eae6a768640b707584d2…
https://github.com/musescore/MuseScore/blob/5979345eae6a768640b707584d2…

This might be enough to get you started.

  • Dale

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