How does Musescore creates MIDI files ?

• Jan 7, 2020 - 17:44

Hello to all of you,

This is a question I would normally have asked on Musescore Github's issues, but it seems that they are disabled, so I'll ask it here :

I'm trying to decrypt some MIDI files from Musescore to use them in another software, but there are some things tha I just can't understand, even after days of research about it...

First : What does the B0 and C0 controllers do ? I have found a few informations about it, but I'm still not sure about it...

Second : Just how does the noteOn/noteOff system works ? There is a 00 90 at the beginning, meaning that there is a note on, but after that... For example, on two different notes, I have the following hexadecimal characters, but I just can't understand how the whole part is done (I just understand the first noteOn part...)

00 90 48 50 83 47 48 00 19 4A 50 83 47 4A 00

This should give me a C quarter note followed by a D quarter note, but I only understand the 4 first digits...

Thank you very much, if you can help me...


Comments

For the record, indeed, we don't use GitHub for tracking issues; we have our own issue tracker here on musescore.org. But we don't use that for ordinary support questions - just for confirmed bug reports and formal feature suggestions. For support questions we use these forums, so you found the right place to ask.

Anyhow, I can't provide much in the way of specific info on your questions, but in general, I can say that we use controllers for single note dynamics (volume changes after a note has sounded) and I assume also for pedal events. Regarding note off, I would assume we don't send those, just a note on with velocity 0, which seems to be the usual convention.

This sounds more like a general question about the MIDI SMF format than something specific to MuseScore. If you search the net for "midi smf format", you'll find plenty of information on how it works.

In short:

1) Status byte Bx is used for various control change messages, for example to set the volume. Status byte Cx is used for program change messages, that is, to select a synth patch (instrument sound).

2) Here's your example hex string parsed into messages:

00: (delta time; indicates how long the interval between messages is)
904850: Status NoteOn on channel #1, note #72, velocity 80.
8347: (delta time)
4800: Running status (NoteOn on channel #1), note #72, velocity 0 (0 is equal to Note Off).
19: (delta time)
4A50: Running status (NoteOn on channel #1), note #74, velocity 80.
8347: (delta time)
4A00: Running status (NoteOn on channel #1), note #74, velocity 0 (0 is equal to Note Off).

"Running status" simply means that if the first byte of a message doesn't have its high bit on, the message consists of data bytes only and the implied status byte is the same as the previous status byte.

Hope this helps.

In reply to by pvrzap

I answer quite lately, but thank you very much for your answer. Now I understand better how it works, all I need to understand yet is how to convert delta time to seconds or vice versa.
Before anyone asks about why I need to do that : I'm currently working on a giant piano software, and I'd like to add a learn mode on it, so I need to highlight the keys that must be pressed at a correct time, and it will be easier for mi to work in seconds/milliseconds than to have to convert it to file's delta time.

In reply to by Benoit Tachet

The delta time in Midi files is not specified in seconds/milliseconds, but rather relative to the tempo, specified as number of ticks (unless SMPTE format is used, which is rare). The file header specifies how many ticks there are per quarter note, and the file itself specifies the tempo; combining these two you get the actual delta time. Additionally, the delta time in ticks is stored as a variable-length quantity, which can have between 1 and 4 bytes depending on the value.
You can check the following reference for more information on the file format: http://www.music.mcgill.ca/~ich/classes/mumt306/StandardMIDIfileformat….

In reply to by afprado

I knew that website, and found my answer before, but thanks ^^. The "hard" part was for the comprehension about the MSB being the check about if the next byte is part of the count or not. The conversion between ticks and milliseconds is also not that tough. I started my code, and I will keep you updated about when it will be done, so we can consider the thread as closed (I hope pretty soon).

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