I exported a simple MIDI file from a Sibelius score that consisted of 3 whole notes in 4/4 time on the piano, with no tempo specified. Here's my analysis of what the specific values mean, but there are still some places that elude me, especially the part following % CHUNK LENGTH DEC = 65. I'm also curious about '00' '90' '45' '4C' '9E'
Can anybody help me fill in the blanks?
% TRANSLATES TO MThd in ASCII
'4D' '54' '68' '64'
% CHUNK LENGTH = 6, NOT SURE WHAT THAT MEANS
'00' '00' '00' '06'
% FORMAT 1
'00' '01'
% = NUMBER OF TRACKS = 2
'00' '02'
% TEMPO PER QTR NOTE = 192? REALLY?
'03' 'C0'
% TRACK 1
% TRANSLATES TO MTrk in ASCII
'4D' '54' '72' '6B'
% CHUNK LENGTH = 41
'00' '00' '00' '29'
'00' % DELTA TIME
% TIME SIGNATURE, nn, 2^dd, bb, cc
'FF' '58' '04'
% = 4/4
'04' '02' '18' '08'
'00' % DELTA TIME
% KEY SIGNATURE
'FF' '59' '02'
% 0 = C
'00' '00'
'00' % DELTA TIME
% TEMPO
'FF' '51' '03'
% tttttt IN MICROSECONDS PER QTR NOTE
'09' '27' 'C0' '00'
% ANNOUNCES A TEXT TO FOLLOW, (LEN TEXT)
'FF' '02'
'0C' % = LENGTH OF TEXT = 12, = 'Copyright copyrightsign2001'?
'43' '6F' '70' '79' '72' '69' '67' '68' '74' '20' 'A9' '20' '01'
% END OF TRACK (DEC = 255 47 0)
'FF' '2F' '00'
% TRANSLATES TO MTrk in ASCII
'4D' '54' '72' '6B'
% CHUNK LENGTH DEC = 65
'00' '00' '00' '41'
'00' 'C0' '00'
'00' 'B0' '79' '00'
'00' 'B0' '40' '00'
'00' 'B0' '5B' '30'
'00' 'B0' '0A' '33'
'00' 'B0' '07' '64' '00'
% LEN, TEXT = Piano
'FF' '03' '05'
'50' '69' '61' '6E' '6F'
%
'00' '90' '45' % ON A
'4C' '9E'
'00' '80' '45' % OFF A
'00' '9E'
'00' '90' '47' % ON B
'4C' '9E'
'00' '80' '47' % OFF B
'00' 'BC'
'00' '90' '48' % ON C
'4C' '9E'
'00' '80' '48' % OFF C
'00' '01'
% END OF TRACK (DEC = 255 47 0)
'FF' '2F' '00'
Check out the attachment for my breakdown of the file. Here are some responses to your questions and comments.
there are still some places that elude me, especially the part following % CHUNK LENGTH DEC = 65.
The second track begins with a Program Change and various Control Change messages.
I'm also curious about '00' '90' '45' '4C' '9E'
The 00 is a delta-time of zero, the 90 45 4C is a Note On message, and the 9E is the beginning of the delta-time of the next event.
% CHUNK LENGTH = 6, NOT SURE WHAT THAT MEANS
After the four bytes that indicate the chunk length, there are 6 bytes in this chunk.
% TEMPO PER QTR NOTE = 192? REALLY?
'03' 'C0'
This part of the header indicates the resolution of this MIDI file is 960 ticks per quarter note. In a MIDI file, the delta-times before each event are in ticks. In this file, there are 960 ticks in a quarter note.
% ANNOUNCES A TEXT TO FOLLOW, (LEN TEXT)
'FF' '02'
'0C' % = LENGTH OF TEXT = 12, = 'Copyright copyrightsign2001'?
'43' '6F' '70' '79' '72' '69' '67' '68' '74' '20' 'A9' '20' '01'
FF 02 is a Copyright meta-event. In the 12 bytes of text data, hex 20 is a space -- the text is "Copyright" space "©" space. After the 12 bytes of text data, the next hex 01 is actually the delta-time of the next event.
Thank you sooo much! Is that a program that generates the MIDI info in your file? Again, amazing work!
Stupid follow-up question, but what's the equation to figure out the durations for the notes? In other words, how do you translate 9E 00 into 3840? (Whole note.)
100 qtr notes per min
960 ticks per beat
%
'00'. '90' '45' '4C'
'9E' '00' '80' '45' '00'
Is that a program that generates the MIDI info in your file?
No. I was just in a creative mood and made the file manually.
what's the equation to figure out the durations for the notes? In other words, how do you translate 9E 00 into 3840? (Whole note.)
The delta-time values use the variable-length quantity format.
In the variable-length quantity format, the high bit of a byte is clear to indicate the value ends with the current byte, or the high bit of a byte is set to indicate the value continues in the following byte. The actual value is in the lower seven bits of each byte. The most significant bits are first, so you just keep putting the value bits on the right end as you encounter them. The maximum number of bytes that can be used is 4, so the maximum value that can be stored is 4 sets of 7 bits that are all ones, in other words, the binary value that is 28 one bits.
[Source: In the Standard MIDI Files Specification, you can see the description of variable-length quantity format on printed page 2 (PDF page 4). By the way, as well as the delta-time values, the other things that use the variable-length quantity format are the length values at the beginning of the following events: FF Meta Events, F0 System Excusive events in a MIDI file, and F7 System Exclusive Packet / Escaped events in a MIDI file.]
Example:
encoded hex : 9 E 0 0
encoded binary : 1001 1110 0000 0000
continue flag : 1 0
decoded binary : 001 1110 000 0000
decoded binary : 00111100000000
decoded binary : (00)00 1111 0000 0000
decoded hex : 0 F 0 0
decoded decimal: 3840
If you are more comfortable with decimal math, the decoding process is like this:
1. Let v be a place to accumulate the decoded value. Start with v as 0.
2. Read a byte from the MIDI file into n.
3. What is the value of n?
A. n is 0 to 127: Calculate v + n and store the result back into v. You are done, so end the process here. v is the decoded value.
B. n is 128 to 255: Continue to step 4.
4. Have you already read four bytes?
A. Yes: This shouldn't have happened. End the process with an error message.
B. No: Calculate (v + (n-128)) × 128 and store the result back into v. Go back to step 2.
Once you know how to decode delta-time variable-length quantity values, you can calculate a note's duration as follows:
In a MIDI file the decoded delta-time values are the number of ticks since the previous event in the track.
In your example MIDI file, each note starting message is followed by a note ending message for the same pitch value, but that won't always be the case. So in more complicated MIDI files, you'll have to keep a running sum of the delta ticks you encounter after the note starting message until you see the corresponding note ending message for the same pitch value.
Once you have the total duration in ticks, you can convert it into an amount of quarter notes by using the "ticks per quarter note" resolution value specified in the MIDI file header. In your example, 3840 ticks / 960 ticks per quarter note = 4 quarter notes.
You don't need to use the tempo value unless you want to convert the durations or positions into seconds. For more information how to do that look at the following post: How to convert ticks to seconds. That post is about calculating a position from the beginning of the song. To calculate a note duration, you'd have to calculate the position of the beginning of the note, the position of the end of the note, then calculate the difference. That will correctly incorporate any tempo changes in the song.
Thank you so much!!!