MIDI format0 데이터를 마이크로 컴퓨터로 취급했을 때의 메모

AVR 마이크로컴퓨터(ATiny85)로 format0의 MIDI 데이터로 곡을 연주시켰을 때의 메모.

MIDI formata0



MIDI 파일의 형식으로 연주 데이터를 트랙마다 나누지 않고 모두 Track0에 들어 있다.
읽기 포인터가 1 개로 좋기 때문에 시간 관리가 용이하고 델타 타임의 사이즈도 작기 때문에 마이크로 컴퓨터에서의 처리에 향하는, DOMINO 등의 시퀀서 소프트의 smf 파일 내보낼 때 옵션으로 지정, 연주에 불필요한 데이터(트랙명이나 저작권, 서포트하고 있지 않는 MIDI 이벤트)는 미리 제거해 두면 사이즈가 작아진다.

델타 시간 = 이전 이벤트로부터의 시간.

format0 데이터 덤프


헤더 (헤더 청크 14byte, 트랙 청크 8byte)




위가 헤더 청크, 아래가 트랙 청크

처음 14byte + 8byte, format0에서 연주에 사용하는 것은 헤더 청크의 마지막 2byte의 시간 단위 (분해능)

헤더 청크




1
2
3
4
5


타입(4byte)
데이터 길이(4byte)
형식 유형 (2byte)
트랙 수(2byte)
분해능(2byte)


트럭 청크




1
2


타입(4byte)
데이터 길이(4byte)


분해능은 시간의 최소 단위(1델타 타임)를 4분 음표를 이 값으로 나눈 값으로 나타내는, 4분 음표의 길이는 메타데이터의 SetTempo로 설정.

분해능 이외에는 사용하지 않는다.

데이터






1
2


델타 타임 (가변 길이)
데이터 (메타 데이터, 시스템 에클 시브, MIDI 데이터)



델타타임

이전 이벤트로부터의 대기 시간, 데이터 길이 가변

가변 길이 데이터

유효 하위 7bit, MSB가 서 있는 경우에는 다음 데이터 있음
0x7F로 마스크하고 7bit 왼쪽 시프트하여 MSB가 0의 데이터가 올 때까지 반복한다.

deltatime_sample.c
        delta_time = 0;
        if( -1 == (sd_c = SMFDATA.smf_getChar())) break;
        while(sd_c & 0x80){  //次データあり
            delta_time = delta_time|(sd_c & 0x7f);
            delta_time <<= 7;
            if( -1 == (sd_c = SMFDATA.smf_getChar())) break;            
        }
        delta_time = delta_time | sd_c; 

MIDI 데이터

0xC0과 0xD0은 2바이트이므로 주의


시스템 에클 시브

0xf0에서 시작하여 0xf7로 끝나는, 지원하지 않으면 원래 데이터로 지웁니다.

메타 이벤트




1
2
3
4


메타 이벤트
이벤트 type
후속 데이터 수
데이터

0xFF
1byte
가변 (후속 데이터를 127byte 이내로 하면 1byte)
후속 데이터 수로 표시된 데이터가 계속


곡을 연주하는데 최저 필요한 것은 SetTempo, 후에는 무시해도 우선은 울린다.

SetTempo (0xFF,0x51,0x03, data1,data2,data3)

4분 음표의 길이(uS), 1델타 타임은 이 값을 분해능으로 나눈 시간.
dat1,dat2,dat3은 8bit 값
long Tempo_val;
Tempo_val = dat1;
Tempo_val <<= 8;
Tempo_val |= dat2;
Tempo_val <<= 8;
Tempo_val |= dat3;

기준 시간 = (사분 음표 길이 μS)/(분해능)
기준 시간 = Tempo_val/midi_division; (midi_division: 분해능)

이 기준 시간을 실제 타이머로 몇 클럭 기다리면 좋은지를 계산하고 기다린다.

delta_count = delta_time × (Tempo_val/midi_division)/(1/Clock)

예)
해상도 = 240 Tempo = 193.5에서 Tempo_val이 0x4BB3D (310077)

기준 시간은 310077/240 = 1291.9875 us
Clock 32KHz
1clock = 1/32000000 32.25 us

1291/32 ≒ 40
이것 정도의 값이 되는 Clock로 한다.

이벤트 발생시 타이머를 클리어하고 다음 이벤트는 delta_count까지 기다리면 된다.

좋은 웹페이지 즐겨찾기