Regression: Unison notes in a shortest value are not played

• Mar 22, 2018 - 13:34
Reported version
2.2
Type
Functional
Severity
S3 - Major
Status
closed
Project

I just received a score from a guitar forum. I made the selection of the two first measures: Sélection.mscz
Something is wrong/weird in the playback (most of the E open first string are not heard) with the last 2.2 : 3d20279
As expected (E are played) with the 2.1.
I try to understand what happens.
Status "normal" for now, potentially "major"


Comments

I suspect this is related to the sound font. I use the FluidR3Mono.sf2 sound font from around 8 March and it plays correctly in 2.2. This was before s.chriscollins started working on the sound font.

Title Regression: Unexpected playback Regression: Unison notes in a shortest value are not played
Severity S4 - Minor S3 - Major

1) Load this test file : test file.mscz
2) Launch playback

Result: the unisons are cutted/ not played when they are in a shortest value than the equivalent notes in another voices.

Other example from the first "selection" file: Sélection3.mscz

To summarize with this new test: test1.mscz
Listen with the 2.1
And now, listen with the fix and the current 2.2 dev./ RC.
The first line / staff is better.
But now, in the second staff / line, we have "holes" in playback, as if the score had the hiccups.
In a word, it's completely unexpected, and worse, alas :(

This is not “unison”, this is using separate voices. Voices are one instrument, and one MIDI channel.

For unison, you need separate MIDI channels, normally by using separate staff lines. (It also was not unison before that commit. Before, it just did not play the longer value.)

With a workaround, you can change your score to split them into separate MIDI channels (attached).

Attachment Size
test1.mscz 7.91 KB

" you can change your score to split them into separate MIDI channels"
Split my score in two separate MIDI channels?
Sorry, but how concretely myself, (and uninformed users), can do that, which steps?

Severity S3 - Major S5 - Suggestion

There will be a FAQ about it. I’ll do a couple of screenshots and write accompanying prose when I get the time, shortly,

In reply to by mirabilos

Seriously, a workaround would be needed to simply hear the notes that appear on the screen / score during playback?
I imagine the surprise of the users who will discover this, and who, of course, will consider it as a bug. And a major bug/regression of course.

It would be unreasonable, after the problems of sound (drums, for example) of 2.1, that the next version, 2.2, has, also, other sound problems. I can not conceive of it.

Eg, with the complete score of which I made a selection of two measures in the first message, the playback is completely hashed. Simply inconcevable, again.
21 notes are missing (see it, in color) during the playback in a score of just 2 pages. In particular measures 13 and 14 are a disaster.
What more can be said?
The complete score: VII La Muerte.mscz

I agree with cadiz1, this is a serious regression. Hopefully it can be fixed, but if it truly is a design limitation of the previous change, I see no alternative to but to recommend reverting it, because in this case the cure seems worse than the disease.

My understanding is that the new fixupMIDI() function works by discarding any subsequent notes of the same pitch that occur while a note is still playing. This means lots of notes that previously sounded will no longer sound. For certain instruments, this might be acceptable - it really wasn't going to be physically possible to play the subsequent note anyhow. But for guitar, also for staves that use multiple voices to represent multiple instruments (or actual voices), this is going to be unacceptable. For example, the following extremely simple passage does not render correctly in either 2.1 or 2.2, but it is far worse in 2.2 than in 2.1:

overlap.png

In 2.1, the worst that happens is the whole note in the first voice gets cut off early. Mildy annoying at worst. Now, the quarter note in the second voice (on beat 3) doesn't sound at all. Disastrous in comparison to 2.1, IMHO.

Sorry this didn't occur to me when initially reviewing the code, but am glad we get to see this now before release so we can consider how to deal with it.

As I re-read the thread for the original issue #12971: Same note in different voices and lengths plays only the length of the shortest note and see the various factors being discussed, I am thinking the "real" solution is to use different MIDI channels for the different voices on a staff, but this is out of the question for 2.2.

I think it plain that in the cases where two notes are sounded simultaneously, we want the longer to win. But in cases where a second note is struck sometime after the first, we have been assuming the desired result is for the second note to not sound at all so the first can continue, and this is, in hindsight, looking like the wrong decision.

So, what if we simply compromised, and continued to discard the shorter note in the first case (where two notes occur at the same tick) but not in the latter cas? It's actually a simpler algorithm, probably faster to process too, and I think gives better results, at least in these cases.

Or maybe there is some other case I am not considering where discard that second note really is preferable? I am having difficulty imagining it, frankly, but there seemed widespread agreement before that this made sense, and that must have been based on something?

Sorry if I chime in without knowing the full details of the implementation, but what about creating a "restrike" key scenario (i.e. at the overlapping note send noteoff+noteon signal, but let the second note sound until the end of the one ending at the latest time) and using it as an alternative to the current one (which is basically a "no restrike", if I understood correctly), depending on a (global?) MuseScore preference set by the user (basically a true/false button in I/O Preferences or similar place)?
ES:
Given:
note1                 |-------------|
note2                        |---|        we could have:
with restrike:    |----|-------|
no restrike:       |-------------|
Given:
note1                 |-------------|
note2                        |-----------|    we could have:
with restrike:    |----|-----------|
no restrike:       |-----------------|

In this case, a user who wants an audio output similar to an organ would just use a "no restrike" option, while a user who wants an output similar to a guitar would use a "restrike" option.
I don't know how difficult would be to implement this and, more importantly, if there would be time enough before the release of 2.2.
Unfortunately, I know really nothing about the midi output interface and I wouldn't even know where to start on it...

I'm in favour of Marc's proposal. Since classical/fingerstyle guitarists commonly use shared noteheads with different durations, this looks like a good solution.

Restrike is possible and it works with our internal synthesizer, not sure how well it would work for midi export or even MIDI out though... It seems the best solution to me. Ok it sounds a bit weird for organ but hell... YouTube video and PR to come.

In reply to by geetar

Title Regression: Unison notes in a shortest value are not played Regression: Unison notes in a shortest value are not played

The current implementation (the one cadiz1 does not seeem to like) does precisely that: the longer note wins.

2.1 would just discard the LONGER note. So, the 2.2 snapshot being complained about plays MORE sound than 2.1 ever did. (In this particular score excerpt, it plays the same AMOUNT of notes as 2.1 did, just some are longer as in 2.1.)

In reply to by [DELETED] 5

BSG might hate this because he needs the non-restriking behaviour, but I could personally live with that for 2.2.

So we’ll need to take notes for what would have to be changed post-2.2… I think the list has already grown to:
• easy way to split voices into separate MIDI channels
• (independent of that) a checkbox, per MIDI channel(!), whether it needs restriking behaviour or not (against the “natural” default, the majority of use cases seems to wish for restriking, so that could be the default)
• instruction of users to use split voices e.g. in SA/TB closed scores and not rely on restriking for those

For visual demo of playback, we’ll then use the current code for restriking channels and mine for non-restriking ones. That could be fun… (but possible) we’d have to merge them (looks doable).

Hm, wait a moment… if we use restriking, the playback fix from my PR would behave the same, as restriking is note off directly followed by note on… @lasconic, is that right? (That would make things easier. We could even use this in 2.2, even though it’s probably too late for an option to disable restriking there.)

Restriking needs to be enabled/disabled per MIDI channel, not per staff, voice, etc. because that’s where the logic happens.

Phew. Took me quite a while to think about it and compose this reply…

if we use restriking, the playback fix from my PR would behave the same, as restriking is note off directly followed by note on…
I don't understand the question. Your PR refers to which PR exactly?

For later, let's speak later... but if we provide channel/voice assignment, restriking is off for me, no need for an option.

In reply to by [DELETED] 5

With "my PR" I meant https://github.com/musescore/MuseScore/pull/3551 which, I think, will also work (for the visual display) when restriking is used.

I've just had another revelation: with restriking, there's a corner case we will have to watch out because it requires non-naive handling: multiple ME_NOTEON for same port/channel/note AT THE SAME TICK. I'll have a look at your PR for restriking, as I have a rough idea how to handle it starting from my code, but will have to see.

Hmm, it’s not all that trivial. Damn. (Yes, of course not as-is but with a slight tweak to provide restriking. I think I could make it work, but it’s harder than I thought at first.)

Considering your “if we provide channel/voice assignment, restriking is off for me, no need for an option” I won’t invest more time into thinking this over. I think your approach is good enough for the rapidly-approaching release, and that’s it then.

"If you are on windows (cadiz ;), you should be able to get a binary to test here."

So, with 1dd229330 (Windows 10), the playback of this file works just fine right now ! :) VII La Muerte, new fix.mscz
And the simple example, too (similar to 2.1) : whole.mscz

  • About the MP3 export: result similar with the 2.1: all notes are played but the longer notes are cutted by the shortest notes. We can live with? mp3.zip

  • About the MIDI export: no problems apparently with the notes. Only a different display at the beginning, first measure eg.
    With 2.1, I receive septuplets, and with the new fix: triplets. Don't know why, but better at first glance :)
    Result 2.1: VII La Muerte 2.1 MIDI.mid
    Result, new fix: VII La Muerte MIDI, new fix.mid

Short proof-of-concept that separate channel assignment also fixes playback, so we will indeed need “only” this past the release. (I already have a backwards-compatible idea for how to make this easy.)

Attachment Size
VII La Muerte_0-4chan.mscz 49.94 KB

In reply to by mirabilos

Just to clarify something said earlier: "2.1 would just discard the LONGER note" - this is not true at all. The longer note was not discarded, it was simply cut short. We still got to hear both notes sound, it was only the length of one of the notes that was incorrect. This is infinitely better than an approach where one of the notes does not play at all. In the simple example I posted in https://musescore.org/en/node/270562#comment-825925, the melody line in voice 2 is just plain missing a note. Not playing the shorter note at all is far worse than cutting off the longer note early in this case. Which is why I suggested the partial solution of only discarding the shorter note when it occurs on the same tick as the longer note.

But indeed, if we are willing to consider using separate channels for voices for 2.2, then that's even better.

To me the restrike option as implemented and demonstrated above seems good, [EDIT: deleted comment about multiple note on's with only a single note off now that I understand better].

I am having trouble understanding the scenario in which not restriking is desired. Can someone show a simple example of when restriking would not be correct? Something about organ music I guess, but as a sometimes organist myself, I still am not seeing it.

OK. Thank you for the tests. We might have some issues with external MIDI hardware used with MIDI out in these cases but I hope the situation is better for everyone : guitar, organ and singers.