MIDI file format Analysis

Source: Internet
Author: User

A MIDI file is a binary file, which generally has the following basic structure: File Header + Data Description

The file header generally includes the file type, because the MIDI file only uses. there are two types of mid Extension: Class 0 and Class 1, and there are more formats of Bitmap files that you are familiar with, so the file header will appear.

The data description part is the subject. Now let's analyze its structure together:

Each MIDI file starts with the following content. Their hexadecimal code is: "4D 54 68 64 00 00 00 06 ff nn dd ".

The first four ASCII characters "mthd" are used to identify whether a MIDI file is used, and the next four bytes indicate the number of bytes in the description part of the file header, which is always 6, therefore, it must be "00 00 06". The meaning of the remaining parts is as follows:

The above is the MIDI file header, and all the subsequent content is actually done. Let's take a look at its composition.

MIDI data is composed of several sub-data in the same format. These Sub-data records all information of a single track in the format of multiple audio tracks. Simply append data to the back of the previous audio track by adding one more audio track,But do not forget to change the NN (number of tracks) in the file header).

First watch the global audio track. Global audio tracks include additional information about a song (such as title and copyright), Song speed, and system code (sysx.

Both global audio tracks and audio tracks containing notes start with "4D 54 72 6B". It is actually an ASCII character "mtrk" followed by a four-byte integer, it indicates the number of bytes of the track, which does not include the first 4 bytes and the four bytes of the track. This can be understood in the following example.

The next step is to record the data. Each data has the same structure: Time Difference + event.

The time difference refers to the time from the previous event to the event. The unit is tick (the minimum time unit of MIDI ). Its structure is special. Here we use binary to describe it.

One byte has eight bits. If only seven bits are used, it can represent 0 ~ 127, and the remaining one is used as a flag. If the number to be expressed is in the above range, this sign is 0. In this case, a 7-bit byte can represent 0 ~ 127 tick. If the number to be expressed exceeds this range (for example, 240), set the flag to 1, record the height of 7 bits, and leave the rest to the next byte, in this example, 240 can be divided into 128*1 + 112. Here, 1 is the first byte to be recorded. With the flag, it should be 10000001, that is, the hexadecimal 81; 112 is the next byte record, and its hexadecimal value is 70: therefore, to indicate the time of 240, it must be written as 81 70. Similarly, to indicate 65535 tick, you can calculate 65535 = 1282*3 + 1281*127 + 1280*127, and then get the result: 83 ff 7f. From this, we can also know how to determine the time difference: as long as the flag bit is 0, it indicates the time difference between reading ends. For example, 82 C0 03 indicates 1282*2 + 1281*64 + 1280*3 = 40963. If the Basic time is 120, there are 341: 043 quartile notes.

The byte that records integers in this way is calledDynamic bytes, It changes its length according to the record integer, which will be used later, so it must be skillfully calculated.

After reading such troublesome things, let's look at something more troublesome:Event. After the interpretation of these standards, we will use some examples to further understand these contents.

Events can be divided into notes, controllers, and system information. These events have a unified expression structure: Type + parameter.

For a note, the valid range is 0 ~ 127, so use 00 ~ 7f, as a "type", can be considered as a note. For example, 3C indicates central C. The most important parameter of a note is the intensity (also called speed: velocity ). For example, 3C 64 indicates a central C note with a decimal intensity of 100.

Because one byte has eight bits, if the remaining one is set to 1 and then joined with the other seven bits, it can represent various information. For the moment, we ignore whether a sound track is global or used to record notes. They are all used to record various events in the final sense, but some of them should be logical when the global audio tracks appear. In this case, we can view the event from the following table:

In the following table, X indicates the audio track 0 ~ F. For example, 81 indicates releasing the Note of the second rail.

The following table lists the FF details in detail. When the number of bytes is determined by the data, the table uses.

These are all the contents of the Midi structure. In the next lecture, we will analyze them using an example.

Some tools should be prepared to write binary (hexadecimal) files. For example, I use VC ++, because learning the MIDI format is nothing more than the software that I want to write, since VC ++ can edit binary files, it will be used. Next, you should find a software that can edit and play the MIDI file, such as cakewalk, so that you can start.

First, write the file header "4D 54 68 64 00 00 06". We will directly write the format of synchronizing multiple audio tracks, first write one audio track, and take 120 as the basic time of a note. In this way, the subsequent bytes are: "00 01 00 01 00 78 ".

Now, if you use cakewalk to open the course, it will fail because the number of audio tracks we specify is 1, but no audio tracks are written. If you change it to "00 01 00 00 78", open it again, it won't go wrong. Therefore, if you change the number of audio tracks in the future, do not forget to report to "TOP.

Change the number of tracks back to 01 and continue our experiment. First, write the audio track header information: "4D 54 72 6B" (mtrk). Because we cannot determine the number of bytes next to it, first assume it is "00 00 00 00 ", I will try again later.

Let's first try to set basic information such as the speed and beat of the song. Assume that the time of a quartile is half a second, that is, 0.5*106 microseconds. Its hexadecimal number is 07a120. Then, let's look at the event table and set the speed to 51, but it must be FF before it, and then it needs 3 bytes as the parameter, so the number of bytes is 03, the parameter is "07 A1 20", that is, "FF 51 03 07 A1 20 ". This is the event part. Do not forget that there is a parameter before it -- time difference. This parameter should be set at the beginning, so the time difference is 00. Therefore, the complete event should be "00 FF 51 03 07 A1 20". We append this section to the end of the MIDI file.

At this time, do not rush to use cakewalk for verification, because we have not reported it to the "superior". That's right, change "00 00 00 00 00 07", which indicates the number of bytes, to "00 00 00 07". If VC ++ is used as the binary file editor, after selecting the event, you can see the length of the selected byte in the status bar. After saving it, use cakewalk to open it. The speed is 120.

Let's set the cycle and adjustment, because a new MIDI with cakewalk will be set to 4/4 by default. in C major, we will change it to 6/8 and a major. Check the event table to know that 58 and 59 are used to set the cycle and adjust the number respectively. Although many parameters are set for the cycle, in the current system, the last two parameters are ignored, and cakewalk also modifies them. Therefore, we only need to set the actually useful ones. The numerator is 6, the denominator is 8, so the first parameter is 06, and the second parameter is 03 (23 = 8 ). Finally, fill in the time difference and the two ignored parameters, which should be "00 FF 58 04 06 03 00"; then look at the adjustment number, a has three escalation numbers, therefore, such an event can be expressed as "00 FF 59 02 03 00 ". In fact, the size adjustment is a ignored parameter. Calculate the number of bytes of the event so far, and then change the previous parameter to "00 00 07" to "00 00 15 ". Save and use cakewalk to open it. Then, enter the five-line spectrum window, and you will be able to verify it immediately. You may have noticed that there are some latencies before entering the five-line window, because we have not set the bytes that can be ignored, and cakewalk is re-verifying them, we will discuss this later.

In the same way, you can easily set the title and copyright of a song. As an exercise, you will not write more here. Now we are learning to write an orbit containing notes. First, you should know what to do: 1. Write the information header of the new audio track; 2. Report an additional audio track to your superiors. Next, we start to write a simple note.

Assume that a mediainfo A is written to the first shot. Here, it may be explained that the notes are counted up from C0, and the count to central C (C5) is a hexadecimal 3C, the mediainfo A should be 45, and a detailed calculation method is provided in the attachment. We know that a note in music usually has three attributes: pitch, intensity, and value. However, in the event table, we do not see any signs that can directly set the value of the notes. In fact, the value of a note is determined by the press time and release time. Let's assume that we want to write an octal note. The Tick number is half of the four-minute note, that is, 60, expressed as 3C in hexadecimal notation. Let's take a look at the notes.

In the event table, 9x is used to open a note. Here we assume that 7th channels are used.(Note that MIDI has 16 channels, and 10th are used as percussion by default. Therefore, do not use 10th channels at this stage (before learning sysx)In 9x, X is 6. Then, let's look at its parameters. One is the note. Here we write 45, and the other is the intensity. We use 70, because it is triggered at the beginning, so the time difference is still 00. In this way, we can use 5th channels to increase the intensity by 112.PressA. The corresponding byte description is "00 96 45 70 ". You don't need to know that the value of it must be 0. It depends on when to release it.

In particular, if the intensity of a note is 0, Midi considers that the user wants to release the key because 9x has opened the channel, therefore, we can directly write a single note with a 00 intensity to determine the value of this note. According to the previous analysis, the time difference should be 3C. Therefore, after writing 3c, we should write 45 notes and its strength 00, that is, "3C 45 00 ". Calculate the number of nodes and update the header information of this track. Then save the number to the disk. Open it with cakewalk and enter the event list window to verify the number.

On this basis, we try to add a four-point music # G behind. Because 96 has opened the channel, we do not need to use 9x every time, just enter the event information. For the voice # G, the hexadecimal value is 44. The time difference is 00 compared to a with the input strength. Therefore, it can be expressed as "00 44 64 ", here we have assumed that the intensity is 100; then we release it. Because it is a four-minute note, the time difference is 78 H. Don't forget that the intensity is 00, its bytes should be expressed as "78 44 00", do the following work, and then verify whether it is correct.

Let's make a more complex experiment: On the basis of the original, add a four-byte central sound D to the first shot of the same track. The append method cannot be used here, because the previous event has passed three octal notes, and whatever it is added, it will only happen in the back, so we need to insert some bytes in front.

9x has opened the channel. We directly Add a NOTE event "00 3E 64" after the note pressed by 9X. The 00 here is obviously a time difference, and 3E is a mediainfo D, 64 is the intensity. That is to say, a is pressed While a is pressed. We press the next key again. When and where can we release it to ensure that the input is an octal note? First, its value is three octal notes, namely 180. Note that 180 is a number greater than 128, its Dynamic bytes should be expressed as "81 34". Where can we input it? If you think entering the time difference after pressing D, or entering the time difference at any place, and then writing "3E 00" can indicate that the concept of time difference is completely misunderstood. In fact, we only need to simply release d When releasing # G, so we should add "00 3E 00" at the end ". After counting the number of nodes, go to cakewalk to verify the number. The sample MIDI file we have written down is attached here.

So far, we should be able to enter any form of notes. However, in addition to the notes, Midi can also include various controllers and system codes, which are no less important than notes, now we will learn how to use controllers.

The Controller is much simpler than the note. We try to add the phase control (PAN) before # G. Its decimal code is 10 and the hexadecimal value is 0a, we set the parameter to 111, that is, the hexadecimal 6f. First, we can find that the controller is BX. Here, X is the same as above, and it is also 6. Next, write the Controller number 0a, and then the parameter 6f. Don't forget that the time difference is 00. Therefore, this byte is "00 B6 0a 6f", which should be placed before the event of releasing # G, and at the same time as pressing # G. However, once a non-note event is used and there is a note event behind it, you must re-notify the opening of the note. This is complicated to say and is easier to do, we only need to slightly rewrite the next note event: It was originally "Time Difference + note + intensity". We add a sign to open the note and become "Time Difference + 9x + note + intensity. After checking the overhead information, go to the cakewalk to perform a further test to check its feasibility.

In fact, if the time difference is 00, the control events will be placed in the track information as much as possible in cakewalk, instead of repeating in the event list. We can use this to set the initial instrument and volume for the audio track, which is used as an exercise and will not be described here.

Other formats, such as the trigger key, are similar to those of the controller. Here it is necessary to remind you of the slide. The music scope of the slide is-8192 ~ 8191, but the parameter is a positive number. For example, to set it to 0, it should be 0-(-8192) = 8192, which is the parameter. The 7-bit double byte of 8192 is represented as "8192 mod 128 = 00 h; 8192 Div 128 = 40h ". If the time difference is 00, it should be expressed as "00 E6 00 40"

Finally, let's look at the system code. The system code is originally "F0 factory id device number format code transfer command specific parameter F7", but in the file, it is not the system code starting with "F0, the number of bytes only records the remaining System Code. For example, the XG reset code is "F0 43 10 4C 00 00 7E 00 F7 ", the file should be written as "00 F0 08 43 10 4C 00 00 7E 00 F7", where the first 00 is the time difference, f0 is the system code mark, and 08 is the number of subsequent bytes. One thing to note is that a few system codes cannot be written together, for example, "00 F0 0d 43 10 4C 00 00 7E 00 F7 F0 aa bb cc F7" or "00 F0 0C 43 10 4C 00 00 7E 00 F7 aa bb cc F7" is not good statement. If the above system code set exists, it can be divided into two events: "00 F0 08 43 10 4C 00 00 7E 00 F7 00 F0 04 aa bb cc F7"

Of course, the system code can be written in any audio track, but we generally consider writing the system code sent before playing the song in the global audio track, and set the time difference to 00.

As a reference, a MIDI sample is attached here.

Although we have only discussed the format of synchronizing multiple audio tracks, for example, the common single-track format, all events are written in only one audio track, that is, it is enough to have a "mtrk. In contrast, the two bytes used to record the number of audio tracks are always "00 01". If the channel for a continuous event is different, you must specify the Channel again (8x ~ Ex ). I will not discuss it in detail here.

  • Hexadecimal notation of notes
  • About instrument Selection
  • RPN and nrpn

In Midi, the central C is C5, the lowest is C0, and the highest is G5. to calculate the hexadecimal format corresponding to any note, you can use this formula:

Assume that the note is no, indicating the audio name N at the O octal. For example, in G2, where n is g and O is 2, the decimal value is O * 12 + N, for the sake of convenience, the value of N is given in the following table:

In this way, the decimal value of G2 is 2*12 + 7 = 31, and the hexadecimal value is 1f.

If you know the hexadecimal notation of a note, you can easily find the note, for example, 64 (16) = 100 (10 ),

The 100 Div 12 = 8,100 mod 12 = 4, and the corresponding note is E8. The formula is:

N = B mod 12; O = B Div 12; (Set B to the decimal number of bytes representing the note)

An instrument is an important factor in Midi. to select all the instrument, you can not only use the Cx sign, but also use bankselect (band selection ), while bankselect is actually completed by Controller 0 and controller 32, their hexadecimal code is 00 and 20 respectively. for example, to select slow violin from the XG standard, it is in the 28h instrument in the 08h band, therefore, the complete code should be "00 B0 00 00 20 08 00 C0 28 ". Let's analyze its composition: here we assume that the time difference is 00, and all information is sent to channel 00, so the first 00 is the time difference, and B0 is the identifier for opening the controller, and specify to send to channel 00. The next 00 is composed of the controller number 00 and the Controller Parameter 00. It actually indicates that the parameter of controller 0 is 0, that is, the bankselect-MSB parameter is 0, followed by the next event, which is "00 20 08", that is, the time difference is 00, and the Controller 20 h is used, the parameter is 08 h, that is, the bankselect-LSB parameter is 08 h, so that the Bank (band) is specified ). The next step is "00 C0 28", which is the so-called patch change event. The time difference is 00 and the parameter is 28 h. This completes the selection of standard instruments.

In fact, it is done by three events. If a selected instrument has a common parameter with the last one, you do not have to repeat the related operations.

In this example, you may find that when you continuously use similar operations, you do not have to specify the operation type each time. For example, if you use the Controller continuously, therefore, the second controller does not use B0 as a flag, but directly uses the Controller number and its parameters. This is the same as the notes. In fact, if you continuously use the patch change event (I mean, if), you do not have to write CX every time. You can open it once. However, for the patch change event, the result of changing the instrument continuously is only the last one.

RPN and nrpn are not mentioned in the previous document. They are actually implemented by four continuous controllers. Assume that you want to use the coarse turning of the RPN event. If its parameter is 4096, its byte is "00 B0 65 00 00 00 64 02 00 06 20 00 26 00 ", let's analyze this Byte: First we first look at the RPN is composed of four controllers-first set the RPN-MSB and RPN-LSB, respectively, the corresponding controller is 65h and 64 h, the RPN code of coarse turning is 2, so MSB is 0 and LSB is 2. Then, Set Data Entry MSB and data entry LSB. The corresponding controllers are 06h and 26 h, 4096 Div 128 = 32, 128 mod = 0, and the hexadecimal numbers are 20 h and 00 h respectively. Therefore, the above bytes are formed. The nrpn and RPN principle is the same, but do not need RPN-MSB and RPN-LSB, and use NRPN-MSB and NRPN-LSB only, their hexadecimal numbers are 63h and 62 h respectively.
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.