파이썬, 미디 파일 구조 분석용 코드 예제
글. 오상문 sualchi@daum.net
미디 파일을 열어서 저장 포맷을 확인하는 파이썬 코드입니다.
표준 미디 파일 구조에 대한 내용은 아래 링크를 참조하세요,
blog.daum.net/sualchi/13720994?category=2090044
# 미디 파일 구조 분석 프로그램 v0.2
# 미디 파일의 헤더 청크와 첫 데이터 청크 정보를 검사함
# 2021.02.09
# by 오상문 sualchi@daum.net
filename = r"c:\temp\test.mid" # MIDI Filename
try:
with open(filename, 'rb') as f:
data = f.read()
except:
print("파일 오픈 에러...")
exit(1)
print("="*60)
print("파일 이름:", filename)
print("="*60)
try:
cType = data[:4].decode()
except:
print("DecodeError 또는 미디 파일 아님")
exit(1)
if cType == "MThd":
print("청크 종류: 헤더", cType)
else:
print("미디 파일 아님")
exit()
# print(data[:4])
size = data[7]
print("다음 데이터 길이:", size, "Bytes")
# print(data[4:8])
trackType = data[9]
if trackType == 0:
print("트랙 유형: 단일 트랙")
elif trackType == 1:
print("트랙 유형: 1개 이상 트랙, 동시 진행")
elif trackType == 2:
print("트랙 유형: 1개 이상 트랙, 순차 진행")
else:
print("트랙 유형: 모름")
# print(data[8:10])
trackCnt = data[11]
print("트랙 수:", trackCnt)
# print(data[10:12])
if data[12] & 0b10000000 == 1:
print("초당 SMTPE 프레임 수:", data[12] & 0b01111111)
print("SMTPE 프레임당 틱 수:", data[13])
else:
unitTime = data[12]*0xff + data[13] # 12, 13
print("단위시간 수:", unitTime, "(4분음표 길이(틱수))")
#print(data[12:14])
print("-"*60)
partList = data.split(b"MTrk")
print("MTrk 데이터 파트 개수:", len(partList)-1) # MTrk 파티 개수
for i in range(len(partList)):
print(i,":", len(partList[i]), "Bytes")
'''
start = 14
cnt = 0
while cnt < trackCnt:
pos = data[start:].index(b"MTrk")
start += pos
print(data[start:start+4].decode(), start)
start += 4
cnt+=1
'''
cType = data[14:18].decode()
if cType == "MThd":
print("청크 종류: 헤더", cType)
elif cType == "MTrk":
print("청크 종류: 데이터", cType)
else:
print("청크 종류: 모름", cType)
# print(data[14:18])
size = data[18]*0xffffff + data[19]*0xffff + data[20]*0xff + data[21]
print("다음 데이터 길이:", size, "Bytes")
#print(data[18:22])
print("데이터:", data[22: 22+size])
print("-"*60)
테스트용 미디 파일
[실행 결과]
============================================================
파일 이름: c:\temp\test.mid
============================================================
청크 종류: 헤더 MThd
다음 데이터 길이: 6 Bytes
트랙 유형: 1개 이상 트랙, 동시 진행
트랙 수: 4
단위시간 수: 120 (== 4분음표시간/단위시간개수)
------------------------------------------------------------
청크 종류: 데이터 MTrk
다음 데이터 길이: 116 Bytes
데이터: b'\x00\xffX\x04\x02\x02\x18\x08\x00\xffY\x02\xfd\x00\x00\xffQ\x03\x08\xb8$\x82
\x89+\xffQ\x03\t\'\xc0\x81m\xffQ\x03\t\x89hx\xffQ\x03\t\xf3\x8d\x82k\xffQ\x03\x08\xb8$
\xd4)\xffQ\x03\t?l\x81t\xffQ\x03\t\xbdYx\xffQ\x03\n\xc5ZB\xffQ\x03\rv\xb0\x811\xffQ\x03
\r\xdf"\x07\xffQ\x03\x10\xa5]\x10\xffQ\x03\x13\x12\xd0\n\xffQ\x03\x16\xe3`\x00\xff/\x00'
------------------------------------------------------------
이상.
[참고] 표준 미디 파일 형식
SMF = <header_chunk> + <track_chunk> [+ <track_chunk> ...]
Header Chunk
- The header chunk consists of a literal string denoting the header, a length indicator, the format of the MIDI file, the number of tracks in the file, and a timing value specifying delta time units. Numbers larger than one byte are placed most significant byte first. header_chunk = "MThd" + <header_length> + <format> + <n> + <division>
"MThd"
- 4 bytesthe literal string MThd, or in hexadecimal notation: 0x4d546864. These four characters at the start of the MIDI file indicate that this
- is
- a MIDI file.
<header_length>
- 4 byteslength of the header chunk (always 6 bytes long&emdash;the size of the next three fields).
<format>
- 2 bytes
0 = single track file format
1 = multiple track file format
2 = multiple song file format
<n>
- 2 bytesnumber of tracks that follow
<division>
- 2 bytesunit of time for delta timing. If the value is positive, then it represents the units per beat. For example, +96 would mean 96 ticks per beat. If the value is negative, delta times are in SMPTE compatible units.
Track Chunk
- A track chunk consists of a literal identifier string, a length indicator specifying the size of the track, and actual event data making up the track. track_chunk = "MTrk" + <length> + <track_event> [+ <track_event> ...]
"MTrk"
- 4 bytesthe literal string MTrk. This marks the beginning of a track.
<length>
- 4 bytesthe number of bytes in the track chunk following this number.
<track_event>
- a sequenced track event.
Track Event
- A track event consists of a delta time since the last event, and one of three types of events. track_event = <v_time> + <midi_event> | <meta_event> | <sysex_event>
<v_time>
- a variable length value specifying the elapsed time (delta time) from the previous event to this event.
<midi_event>
- any MIDI channel message such as note-on or note-off. Running status is used in the same manner as it is used between MIDI devices.
<meta_event>
- an SMF meta event.
<sysex_event>
- an SMF system exclusive event.
Meta Event
- Meta events are non-MIDI data of various sorts consisting of a fixed prefix, type indicator, a length field, and actual event data.. meta_event = 0xFF + <meta_type> + <v_length> + <event_data_bytes>
<meta_type>
- 1 bytemeta event types:
Type | Event | Type | Event |
0x00 | Sequence number | 0x20 | MIDI channel prefix assignment |
0x01 | Text event | 0x2F | End of track |
0x02 | Copyright notice | 0x51 | Tempo setting |
0x03 | Sequence or track name | 0x54 | SMPTE offset |
0x04 | Instrument name | 0x58 | Time signature |
0x05 | Lyric text | 0x59 | Key signature |
0x06 | Marker text | 0x7F | Sequencer specific event |
0x07 | Cue point |
<v_length>
- length of meta event data expressed as a variable length value.
<event_data_bytes>
- the actual event data.
System Exclusive Event
- A system exclusive event can take one of two forms:
sysex_event = 0xF0 + <data_bytes> 0xF7 or sysex_event = 0xF7 + <data_bytes> 0xF7
In the first case, the resultant MIDI data stream would include the 0xF0. In the second case the 0xF0 is omitted.
Variable Length Values
Several different values in SMF events are expressed as variable length quantities (e.g. delta time values). A variable length value uses a minimum number of bytes to hold the value, and in most circumstances this leads to some degree of data compresssion.
A variable length value uses the low order 7 bits of a byte to represent the value or part of the value. The high order bit is an "escape" or "continuation" bit. All but the last byte of a variable length value have the high order bit set. The last byte has the high order bit cleared. The bytes always appear most significant byte first.
Here are some examples:
Variable length Real value 0x7F 127 (0x7F) 0x81 0x7F 255 (0xFF) 0x82 0x80 0x00 32768 (0x8000)
대치동, 잠실 코딩 교육 문의: 010-4440-0813 (오상문 원장)
'Python 활용' 카테고리의 다른 글
엑셀 데이터 전처리 쉽게하기 (0) | 2021.05.08 |
---|---|
엑셀 데이터 전처리 (Python / Pandas) (0) | 2021.05.07 |
파이썬, Pandas로 엑셀 파일 읽기, 쓰기 (0) | 2021.04.24 |
파이썬, Pandas의 Series, DataFrame 자료 예제 (0) | 2021.04.24 |
파이썬, PyAudio 설치 에러 (0) | 2021.02.22 |