
이 글은 Standard MIDI-File Format Spec. 1.1을 번역 및 요약한 글입니다. 원문을 읽으시려면 여기를 눌러주세요.
MIDI 파일은 여러 개의 MIDI Stream으로 구성되었다.
MIDI Stream은 시간에 따라 각 이벤트의 정보를 저장한다.
음악, 시퀀스, 트랙 구조, 템포, 박자표(time signature; 4/4 등) 정보 등이 지원된다.
MIDI 파일에는 큰 숫자를 저장하기 위해 Variable Length Quantity라는 개념을 사용한다. 이는 가변 길이로 수를 나타낼 수 있는 체계로, 저장할 수를 7비트 단위로 분리하여 순서대로 바이트 단위로 배치하되, 한 바이트에 7비트를 배치하고 남는 최상위 비트에는 1을 적는다. 한 숫자를 나타내는 마지막 바이트의 최상위 비트에는 0을 적는다. 0의 경우 0으로 저장된다.
VLQ는 무한히 길어질 수 있는 것이 아니라 0xFFFFFF7F로 저장되는 값인 0FFFFFF까지만 확장될 수 있다.
예시) 0x2000 은 2진수로 나타내면 0010 0000 0000 0000 이고, 이를 7비트 단위로 나누면
00 | 1000000 | 0000000 이므로 그 중 필요 없는 맨 앞의 두 비트는 제거한 다음, 위의 규칙에 따라 나타내면1100 0000 0000 0000 이 되므로 0xC000으로 저장된다.
MIDI 파일은 Chunk 구조로 이루어져 있다. 모든 Chunk는 Chunk의 이름을 나타내는 4byte의 아스키 문자 배열과 Chunk의 길이를 나타내는 4byte의 Big-Endian 숫자를 가진다. 이 숫자에는 데이터의 길이가 적혀 있어, 아스키 문자 배열 및 길이를 나타내는 수가 차지하는 8byte는 포함되지 않는다.
MIDI 파일의 Chunk는 Header Chunk와 Track Chunk로 나누어진다. Header Chunk는 MIDI 파일의 대표적인 정보를 나타내는 Chunk이다. Track Chunk는 최대 16개의 MIDI 채널을 가질 수 있는 MIDI Stream을 저장하는 Chunk이다. Track Chunk를 여러 개를 이용하여 이후 다룰 개념인 Track, Output, Pattern, Sequence, Song을 모두 구현할 수 있다.
MIDI 파일은 반드시 하나의 Header Chunk로 시작하며 그 이후 하나 또는 여러 개의 Track Chunk가 있는 구조를 띈다.
다음은 Header Chunk의 문법을 나타낸 도식이다.
Header Chunk의 Chunk Type은 'MThd'이다.
Format, ntrks, division은 data영역으로 각각 16비트 (word) Big Endian의 수가 저장된다.
Format은 0, 1, 또는 2의 값을 가지는데 각각
| 값 | 파일 |
|---|---|
| 0 | 파일이 하나의 multi-channel track을 가진다. |
| 1 | 파일이 하나 이상의 simultaneous track을 가진다. |
| 2 | 파일이 하나 이상의 sequentially independent single-track 패턴을 가진다. |
을 나타낸다.
Ntrks는 이후로 등장하는 Track Chunk의 개수이다. 만약 Format의 값이 0이라면 Ntrks의 값은 항상 1이 된다.
Division은 다음과 같이 구성되어 있다.
Division의 15번째 비트가 0이라면, 0부터 14까지 14비트에 한 비트(Beats; 4분음표)당 몇 개의 tick을 사용할 지를 저장한다. 만약 저 위치에 저장된 값이 96이라면, 8분음표 두 개 사이의 간격은 48ticks가 된다.
Division의 15번째 비트가 1이라면, 8비트부터 14비트는 SMPTE 규격에 따라서 -24, -25, -29, -30 중 하나가 된다. (2의 보수를 취해서 적음) 이는 초당 프레임 수를 나타내는 지표이다. 0비트부터 7비트까지는 frame의 해상도를 나타낸다. 보통 4 (MIDI Time Code resolution), 8, 10, 80 (bit resolution) 또는 100이다.
MIDI 파일은 반드시 템포와 박자표를 지정해야 한다. 기본값은 박자는 4/4, 템포는 120비트이고, 이는 트랙별로 저장된다. 형식 0, 1의 경우 항상 박자와 템포가 같기 때문에 첫 트랙에 박자표와 템포를 저장하는 메타 이벤트를 포함시킨다. 트랙별로 템포, 박자표가 저장되기 때문에 형식 2인 MIDI 파일의 경우 템포가 달라지는 Chunk마다 박자, 템포를 다르게 지정할 수 있다.
Track Chunk는 음악 데이터가 저장되는 곳이다. Track Chunk는 다음과 같이 나타낼 수 있다.
MTrk event는 다음과 같이 정의된다.
Delta Time이란 Variable Length Quantity로, 이전 이벤트가 시작된 후로부터 해당 이벤트가 실행될 시간의 간격을 뜻한다. 두 이벤트가 동시에 실행된다면, Delta Time은 0이 된다. 여기에 Delta time은 항상 존재한다면서 이상한 문장이 덧붙여져 있는데 무슨 뜻인지는 모르겠다.
(Not storing delta-times of 0 requires at least two bytes for any other value, and most delta-times aren't zero.)
Event는 MIDI Event거나 Sysex Event거나 Meta Event이다. MIDI Event는 MIDI Message를 저장한다.
몇 가지 정해진 Meta Event가 있으나 모든 Meta Event를 프로그램이 지원할 필요는 없다.
| Status D7----D0 nnnn is the MIDI channel no. | Data Byte(s) D7----D0 | Description |
|---|---|---|
| 1000nnnn | 0kkkkkkk 0vvvvvvv | Note Off event. This message is sent when a note is released (ended). (kkkkkkk) is the key (note) number. (vvvvvvv) is the velocity. |
| 1001nnnn | 0kkkkkkk 0vvvvvvv | Note On event. This message is sent when a note is depressed (start). (kkkkkkk) is the key (note) number. (vvvvvvv) is the velocity. |
노트 number는 하단에 첨부되어 있다.
위에서 설명한 대로 이들은 반드시 MIDI 파일 내에 한 번은 등장해야 한다.
FF 51 03 tttttt Set tempo
이 Meta Event는 템포의 변경을 의미한다. tttttt라고 쓰인 자리(24-bit value)에 변화할 템포를 넣는다. 여기에는 4분음표의 길이를 SMPTE Time code (MIDI Time Code)로 표시할 수 있다.
FF 08 04 nn dd cc bb Time Signature
nn은 박자표의 분자, dd는 박자표의 log2(분모)를 나타내고, cc, dd는 사실상 무시해도 되는데, cc는 4분음표를 24 MIDI Clock이라고 두었을 때, 메트로눔이 몇 MIDI Clock마다 한 번 소리를 낼지(click)를 정하는 값이고, bb는 32분음표 몇 개가 MIDI-4분음표 몇 개를 나타내는 지를 표시하는 값이다.
이 부분이 이해가 안 갈 수가 있는데, 32분음표는 8개 모여야 4분음표가 되는 것은 자명하다. 하지만 몇몇 프로그램은 32분음표 10개를 4분음표 한 개로 계산하는 등의 기능을 지원하기 때문에 만들어진 인자라고 한다. 그냥 08으로 두면 될 것 같다. 심지어 이 두 기능은 대부분의 프로그램에서 지원되지 않는다.
예를 들어 6/8박자라고 생각하고, 한 마디에 두 번 메트로눔이 울리도록 설정하고 싶다면 24 * 3 / 2 = 36이므로, nn은 0x06, dd는 0x03이다. cc에는 0x24(십진수로 36), dd는 0x08을 적으면 된다.
(Middle C = C4)
| Octave | Note Numbers | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| C | C# | D | D# | E | F | F# | G | G# | A | A# | B | |
| -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 0 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
| 2 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
| 3 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
| 4 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
| 5 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 |
| 6 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |
| 7 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
| 8 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
| 9 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 |
| PC# | Family | PC# | Family |
|---|---|---|---|
| 1-8 | Piano | 65-72 | Reed |
| 9-16 | Chromatic Percussion | 73-80 | Pipe |
| 17-24 | Organ | 81-88 | Synth Lead |
| 25-32 | Guitar | 89-96 | Synth Pad |
| 33-40 | Bass | 97-104 | Synth Effects |
| 41-48 | Strings | 105-112 | Ethnic |
| 49-56 | Ensemble | 113-120 | Percussive |
| 57-64 | Brass | 121-128 | Sound Effects |