표준 미디 파일 구조
글. 오상문 sualchi@daum.net
표준 미디 파일(SMF)은 데이터 블록, 즉 청크(chunk) 단위로 이루어져 있습니다. 앞에 헤더 청크가 나오고 뒤에 한 개 이상의 트랙 청크가 나타납니다.
SMF = <헤더_청크> + <트랙_청크> [+ <트랙_청크> ...]
[참고] 확장된 미디 파일 형식
GM(General MIDI), GS(General Standard), XG(eXtended General MIDI) 등도 있습니다.
헤더 청크(Header Chunk)
헤더 청크는 헤더를 나타내는 문자열(“MThd”), 길이 표시부, MIDI 파일 형식, 파일의 트랙 수, 델타 시간 단위를 지정하는 타이밍 값으로 구성됩니다. 참고로 1 바이트보다 큰 숫자 값은 최상위 바이트를 먼저 배치합니다(예를 들어, 4바이트 크기이면 최상위바이트-상위 바이트-하위바이트-최하위바이트 순서로 배치됩니다).
헤더_청크 = 헤더_문자열 + <헤더_길이> + <형식> + <n> + <division>
헤더_문자열은 “MThd” 문자열이며 16진수 값으로는 0x4d546864입니다. 이 문자열은 이 파일이 미디(MIDI) 파일임을 알려줍니다.
헤더_길이는 4바이트 구조이며 헤더 청크의 정보 길이는 항상 6이며 바이트 단위입니다. 이것은 헤더 문자열과 헤더길이 정보 이후에 6바이트 길이 정보가 있다는 의미입니다. 6바이트 정보는 각 2바이트씩 나뉜 세 가지 정보가 나타납니다.
형식 정보는 2바이트 길이이며 다음과 같은 값을 가질 수 있습니다.
0 = 한 트랙(single track) 파일 형식
1 = 다중 트랙(multiple track) 파일 형식, 동시 진행
2 = 다중 노래(multiple song) 파일 형식
0번 형식은 모든 미디 데이터가 한 트랙에 저장됩니다. 다중 트랙을 한 트랙으로 저장하면 편집이 불가능하므로 0번 형식은 최종 연주 목적으로 만들 때 사용할 수 있습니다.
1번 형식은 미디 파일에서 일반적으로 사용됩니다. 여러 트랙으로 나누어 저장하므로 각 트랙별로 편집이 가능하며 각 트랙마다 서로 다른 박자와 템포 정보를 가질 수 있습니다.
2번 형식은 여러 트랙을 사용하지만 트랙마다 공통된 박자와 템포를 사용합니다. 드물게 사용되는 형식입니다.
<n>은 2바이트 길이이며 헤더 청크 뒤에 나타나는 트랙 개수를 의미합니다.
<division>은 2바이트 길이이며 델타 타이밍을 위한 시간 단위입니다. 양수 값이면 비트 당 단위를 나타냅니다. 예를 들어, 96은 비트 당 96 틱을 의미합니다. 값이 음수이면 델타 시간은 SMPTE 호환 단위입니다.
# 파이썬에서 <division> 계산하기
if high_byte & 0b10000000 == 1: # 음수인 경우
print("초당 SMTPE 프레임 수:", high_byte & 0b01111111)
print("SMTPE 프레임당 틱 수:", low_byte)
else: # 양수인 경우
unitTime = high_byte*0xff + low_byte
print("단위시간 수:", unitTime, "(4분음표 길이(틱 수))")
트랙 청크(Track Chunk)
트랙 청크는 트랙 청크를 의미하는 문자열, 트랙의 길이, 트랙을 구성하는 실제 이벤트 데이터로 이루어져 있습니다.
트랙_청크 = "문자열" + <길이> + <트랙_이벤트> [+ <트랙_이벤트> ...]
1. 문자열은 4 바이트 길이 문자열이고 “MTrk”입니다. 이것은 트랙 청크의 시작임을 의미합니다.
2. <길이>는 4바이트 길이 숫자이며 이후 나오는 트랙 청크의 길이입니다.
3. <트랙_이벤트>는 일련의 트랙 이벤트 정보 모음입니다. 트랙 이벤트는 마지막 이벤트 이후의 델타 시간과 세 가지 유형의 이벤트 중 하나로 구성됩니다.
트랙 이벤트 = <v_time> + <midi_event> | <meta_event> | <sysex_event>
<v_time>은 은 이전 이벤트에서이 이벤트까지의 경과 시간(델타 시간)을 지정하는 가변 길이 값입니다.
<midi_event>는 note-on(지속) 또는 note-off(휴식)과 같은 MIDI 채널 메시지입니다. 실행 상태는 MIDI 장치들에서 이용되는 것과 동일한 방식으로 사용됩니다.
<meta_event>는 SMF 메타 이벤트(meta event)입니다.
<sysex_event>는 SMF 시스템 독점 이벤트(exclusive event)입니다.
메타 이벤트(Meta Event)는 비고정 MIDI 데이터입니다. 접두사, 유형, 길이 필드, 실제 이벤트 데이터로 구성됩니다. 표준 미디 규격에는 없는 정보이며, 트랙 이름, 악기 이름, 템포/박자 변화, 가사 등의 정보를 다룰 수 있습니다.
meta_event = 0xFF + <meta_type> + <v_length> + <event_data_bytes>
<meta_type>은 표를 참조하세요.
<v_length>는 메타 이벤트 데이터의 길이입니다.
<event_data_bytes>는 실제 이벤트 데이터입니다.
[표] <meta_type> 타입(1바이트)
--------------------------------------------
형태 이벤트
--------------------------------------------
0x00 순서 번호
0x01 텍스트 이벤트
0x02 저작권 알림
0x03 시퀀스 또는 트랙 이름
0x04 악기 이름
0x05 가사 텍스트
0x06 마커(Marker) 텍스트
0x07 큐 포인트(Cue point)
0x20 미디 채널 접두 할당(MIDI channel prefix assignment)
0x2F 트랙 종료
0x51 템포 설정(Tempo setting)
0x54 SMPTE 오프셋(offset)
0x58 박자표(Time signature)
0x59 키 기호(Key signature); 샵/플랫
0x7F 시퀀서 특정 이벤트
--------------------------------------------
시스템 독점 이벤트(System Exclusive Event)는 다음 두 가지 형식을 가질 수 있습니다.
sysex_event = 0xF0 + <data_bytes> 0xF7
또는
sysex_event = 0xF7 + <data_bytes> 0xF7
첫 번째 경우 MIDI 데이터 스트림에 0xF0이 포함됩니다. 두 번째 경우에는 0xF0이 생략됩니다.
가변 길이 데이터 값들(Variable Length Values)
이벤트의 데이터 값들은 가변 길이의 수량(예, 델타 시간 값)으로 표현됩니다. 가변 길이 값은 값을 보유하기 위해 최소 바이트 개수를 사용하므로 어느 정도 데이터 압축 효과가 있습니다.
가변 길이 값은 바이트의 하위 7 비트를 사용하여 값 또는 값의 일부를 나타냅니다. 바이트의 최상위 비트는 "종료"또는 "연속"을 의미하는 비트입니다. 가변 길이 값의 마지막 바이트를 제외하고 모두 최상위 비트가 1입니다. 마지막 바이트는 최상위 비트가 0입니다. 바이트 집단은 항상 최상위 바이트가 먼저 위치합니다. 다음은 가변 길이 값의 예입니다.
0x7F 127 (0x7F) 0x81 0x7F 255 (0xFF) 0x82 0x80 0x00 32768 (0x8000)
[안내] 미디 표준 포맷 레퍼런스 사이트 (간단한 회원 가입 후에 사용 가능)
https://www.midi.org/specifications-old/item/the-midi-1-0-specification
<이상>
'소프트웨어 개발&환경' 카테고리의 다른 글
MVC와 MTV 디자인 패턴 (0) | 2021.06.18 |
---|---|
윈도우 환경 플로터 개발환경 셋팅 (0) | 2021.06.03 |
아나콘다(Anaconda) 설치, 가상환경, 프롬프트 conda, pip 명령 (0) | 2021.02.14 |
Git, Github 저장소 명령어 (0) | 2021.01.26 |
앱인벤터에서 진화한 코듈라(KODULAR) (0) | 2021.01.14 |