Piano renders as percussion on SMF import with Yamaha XG SysEx block

• Nov 3, 2015 - 09:13
Type
Functional
Severity
S3 - Major
Status
closed
Project

If an SMF contains a Yamaha SysEx block, then the routine which recognises PartMode as Percussion kicks in on all channels and erroneously sets the Part to Drumkit in the mixer.

Details here.....
https://musescore.org/en/node/82241

The routine is applying Percussion PartMode to channels not set to Percussion in the SysEx block.

If you need to know more about Yamaha XG SysEx then ask me - I am very knowledgable on the subject.


Comments

I've just been taking a look at the code which can be found at line 785 of midifile.cpp

It checks through the SysEx block to see if PartMode is set to anything other than 0 and if that is the case sets the track to be a drum track.

The flaw in this logic, however, is that if the MIDI file format is 0 there is only 1 track or - if the format is 1 but there is only one instrument. Consequently, as the routine is not taking channel into account it is setting the track as a drum track even though the channel for the data is other than that specified in the SysEx block.

The code needs modifying to check that the Channel for the PartMode set <> 0 is the same as the channel for the rest of the track.

It needs to be altered to something like

if (buffer[6] != 0 && buffer[4] == Channel )
{
_drumTrack = true;
}

But I have no idea where the MIDI Channel is stored or how to pass it to the sub routine

Status (old) active patch (code needs review)

PR: https://github.com/musescore/MuseScore/pull/2395

@ChurchOrganist: You practically had it. Here's how to get the channel at this point in the code.

This fully fixes this issue as it is currently worded, but a related issue remains: if the SysEx event is not referring to the current track and channel, how can we set _drumTrack = true on the track and channel it is referring to? This requires the current track to be "aware of" and have access to all of the other tracks, and this is not currently possible without major restructuring of the code. Additionally, the way MuseScore handles MIDI tracks vs MIDI channels is not helpful for this. Fortunately, this issue is largely theoretical because if the drum track is the 10th channel (channel=9), which it will be for all standards-compliant MIDI files, then it will be rendered as a drum track anyway. It's also possible that the SysEx event will be repeated on the relevant track in which case it will be set as a drum track then.