본문 바로가기

유니티

MIDI 파일을 분석 해보자 3 - 트랙 청크

트랙 청크 구조

 

청크 타입(4바이트) / 길이(4바이트) / 이벤트(가변)

* 이벤트(가변)는 델타 타임(1~4바이트), 이벤트 데이터로 구성되어 있음.

 

 

청크 타입 : 이 청크가 어떤 청크인지 알려주는 역할, 예) 헤더청크냐 트랙청크냐

 

길이 : 길이 뒤에 나열되는 데이터들의 길이를 나타낸다.

 

- 이벤트

델타 타임 : 이벤트가 어느 시점에 실행될지 기록되어 있음.

               가변이므로 다음 바이트가 델타 타임일 경우에는 첫 번째 비트가 1, 아니라면 0이다.

 

이벤트 데이터 : 메타, 시스템, 미디 이벤트가 있으며, 각 이벤트를 구분하는 방법은 첫 번째 바이트를 보면 알 수 있다.

                     FF는 메타, F0~FE는 시스템, 00~EF는 미디

 

- 기타

러닝 스테이터스 : 80~EF 사이의 값과 동일한 메시지가 반복될 때, 이전 스테이터스를 재활용하여 효율을 높인 것.

 

 

 

이제 실제 파일로 분석해보자. 지난 번과 같은 파일이다.

 

갑자기 많아진 양에 정신이 아득해진다..

 

- 청크 타입(4바이트) / 길이(4바이트) / 이벤트(가변)

 

4D 54 72 6B 를 아스키 코드로 변환하면 MTrk 이 된다.

 

 

- 청크 타입(4바이트) / 길이(4바이트) / 이벤트(가변)

 

00 00 00 41 길이가 10진수로 65인것을 알 수 있다.

 

 

- 청크 타입(4바이트) / 길이(4바이트) / 이벤트(가변)

 

* 첫 번째 이벤트

00 FF 58 04 04 02 18 08 맨 앞 00은 델타 타임이며 최상위 비트가 0이므로 다음 바이트는 이벤트 데이터임을 알 수 있다. FF 58 04 nn dd cc bb의 형태를 띠고 있는데 FF는 메타 이벤트, 58은 Time signature(박자표)를 의미한다.

 

nn은 분자, dd(2제곱)는 분모, cc는 메트로놈 틱, bb는 4분음표 한개당 32분음표의 수를 의미한다. 이를 조립해보면

 

4 / 4 박자, 18 메트로놈 틱(24주기), 32분음표는 4분음표 한개당 8개(일반적으로 8개 고정)

 

 

* 두 번째 이벤트

00 FF 59 02 00 00 맨 앞 00은 델타 타임. FF 59 02 sf mi의 형태를 띠고 있는데 59는 Key signature(조표)를 의미한다.

 

sf는 키이며 음수일 경우 플랫이며 양수는 샵을 의미합니다.

mi는 메이저(0),마이너(1)를 의미합니다. 이를 조립해보면

 

C 메이저가 되겠습니다.

 

 

* 세 번째 이벤트

00 FF 51 03 07 A1 20 00은 델타 타임. FF 51 03 tt tt tt의 형태이며 51은 set tempo(빠르기 설정)를 의미한다.

 

07 A1 20은 10진수로 500000이며 마이크로초를 의미한다. 초로 환산하면 0.5초가 된다.

4분음표 한개가 연주되는 시간이 0.5초가 됨을 뜻한다.

 

 

* 네 번째 이벤트

00 B0 79 00 00은 델타 타임. BX 컨트롤/모드번호 새로운값 형태이며 Control/Mode Change(효과 바꾸기)를 의미한다.

 

0번 채널의 효과/모드를 바꾸며 컨트롤 번호는 79.

 

 

* 다섯 번째 이벤트

00 C0 00 Program Change(악기 바꾸기)를 의미한다.

 

0번 채널의 악기를 바꾼다.

 

 

* 여섯 번째 이벤트

00 B0 07 64 효과 바꾸기(메인 볼륨 조절)

 

0번 채널의 볼륨을 100으로 바꾼다.

 

 

* 일곱 번째 이벤트

00 0A 40 Continuous controller #10

 

 

* 여덟 번째 이벤트

00 5B 00 Undefined on/off (0 : off, 127 : on)

 

 

* 아홉 번째 이벤트

00 5D 00 Undefined on/off (0 : off, 127 : on)

 

 

* 열 번째 이벤트

00 FF 21 01 00 FF 21 01 pp 형태를 띠고 있으며 미디 포트를 의미한다.

 

미디 포트는 0번

 

 

* 열한 번째 이벤트

00 90 3C 50 9X 노트번호 음의세기 형태를 띠고 있으며 실질적인 연주 이벤트인 미디 이벤트이다.

00 델타 타임, 0번 채널에 5옥타브 도(3C)를 50의 강도로 연주할 것을 의미한다.

 

 

* 열두 번째 이벤트

83 47 3C 00 열한 번째 이벤트와 연관있는 이벤트이다. 음을 연주하라는 상태 바이트인 9X가 등장하고 음을 그만 연주하라는 상태 바이트가 등장하기 전까지는 계속 음을 연주하게 되는데, 연주를 멈추기 위한 상태 바이트(8X)대신 음의 세기를 0으로 줄여 사실상 연주를 멈춘 것과 같은 효과를 주었다.

 

83 47은 델타 타임이며 이진수로 표현하면

(1000 0011) (0100 0111)

? 최상위 비트를 통해 다음 바이트의 델타 타임 여부를 알 수 있음.

 

최상위 비트를 제외하고 델타 타임의 각 바이트들을 이어 붙여준다.

1000 0011 0100 0111 = 111000111 = 455(10)

 

이제 조립해보자.

 

455 델타 타임에 5옥타브 도를 0의 강도로 연주할 것을 의미한다. (사실상 연주 오프)

 

 

? 8X라는 노트를 끌 수 있는 상태 바이트가 존재하지만 왜 사용하지 않을까?

그 이유로 파일의 용량을 줄이기 위해서가 아닐까 싶다. 위의 예시를 가지고 살펴보자.

 

00 90 3C 50 (4바이트)로 음을 연주하고 이제 8X를 이용하여 음을 꺼보자.

83 47 80 3C 00 (5바이트)로 음을 껐다.

 

차이점이 보이는가?

기존에는 83 47 3C 00 (4바이트)만을 이용하여 8X 상태 바이트를 이용하는 것보다 1바이트를 절약할 수 있게되었다.

또한 다음에 오는 노트들도 상태 바이트 9X를 생략할 수 있기 때문이기도 하다.

 

 

* 열세 번째 이벤트

19 3C 50 음을 연주하라는 이벤트이다. 음을 연주하라는 상태 바이트가 없었는데 어떻게??

앞서 열한 번째 이벤트에 존재했던 9X 상태 바이트가 다른 상태 바이트가 나타나기 전까지는 유지되고 있다고 봐야한다.

 

그러므로, 그 전 이벤트로부터 25 델타 타임 뒤에 5옥타브 도를 50세기로 연주하라는 의미이다.

 

 

* 열네 번째 이벤트

01 FF 2F 00 은 트랙의 끝을 의미한다.

 

그 전 이벤트로부터 1 델타 타임 뒤에 트랙을 끝마침을 말한다.

 

 

 

이하 나머지 데이터들은

 

큰 보표로써 낮은 음자리표를 표현하기 위해 추가된 트랙이므로 생략하도록 하겠습니다.

 

 

분석용으로 잘 사용한 123.mid

 

 

* 상태 바이트, 역할 등을 분류해둔 사이트

www.midimountain.com/midi.html

 

Screenshots MidiMountain

 

www.midimountain.com

 

 

-------

이제 대략 분석이 끝났으니 머리 속에 그려둔 프로그램을 만들어 볼 차례

 

다시 얼마나 쉴진 모르겠지만 금방 하게 되겠지