【第1章 MIDIとは何か】
1. MIDIの本質
MIDI(Musical Instrument Digital Interface)は「音を録音するデータ」ではなく、
どの鍵盤をいつ・どれくらいの強さで押したかを記録する「演奏指示データ」です。
例:
NoteOn(channel=1, note=60, velocity=80, time=0)
NoteOff(channel=1, note=60, velocity=64, time=480)
→ 「チャンネル1のC4を強さ80で押し、480ティック後に離す」という意味。
実際の波形データは含まれません。
【第2章 MIDIを譜面化する原理】
1. MIDI → 音符への変換の考え方
譜面化では、次の変換を行います。
| MIDIデータ項目 | 楽譜上の意味 |
|---|---|
| note(音高) | 音符の高さ(ド・レ・ミなど) |
| velocity | 音の強さ(f, pなど) |
| time / delta | 音符の長さ・開始タイミング |
| track/channel | パート(右手・左手、楽器など) |
2. 拍子とテンポ
MIDIファイルにはテンポ(microseconds per beat)と拍子情報も含まれています。
これをもとに時間(ticks)を四分音符や八分音符に変換します。
例:
tempo = 500000 µs/beat → 120 BPM
480 ticks = 1 beat → 1 beat = 四分音符
【第3章 実際の手法(3パターン)】
方法A:MuseScoreなどの楽譜ソフトで変換(最も簡単)
- 無料ソフト MuseScore を開く
- メニュー「ファイル → インポート → MIDIファイル」
- 自動で譜面化される
- 表示された譜面を手動で修正
- MusicXML・PDFなどで保存可能
※ 注意:
リズムが細かすぎる場合、タイの処理や拍子揺れにより「見づらい譜面」になることがあります。
その場合はMIDIを事前に量子化(Quantize)しておくときれいになります。
方法B:Python + music21でプログラム的に譜面化(再現性重視)
(1) ライブラリ準備
!pip install music21
(2) 基本スクリプト
# Program Name: midi_to_sheet.py
# Creation Date: 20251014
# Overview: Convert MIDI file into readable musical score (MusicXML/PDF)
# Usage: python midi_to_sheet.py input.mid
from music21 import converter, instrument, note, chord
# パラメータ設定
input_midi = "input.mid"
# MIDI読込
score = converter.parse(input_midi)
# 譜面を画面表示(Jupyter環境ではPDF風に可視化)
score.show()
# MusicXML形式で保存
score.write('musicxml', fp='output.xml')
(3) 各処理の意味(日本語+英語)
# converter.parse():
# MIDIファイルを読み込み、音符・休符・テンポ・調号などを自動認識する
# Read a MIDI file and automatically detect notes, rests, tempo, and key signature
# score.show():
# 標準ビューアで楽譜として表示(PDFやMuseScoreで開く)
# Display the parsed score in a sheet music viewer
# score.write('musicxml', fp='output.xml'):
# 楽譜形式(MusicXML)に変換し保存
# Export the score into MusicXML format (universal standard for sheet music)
方法C:より精密な解析を行う場合(多声部・拍子・テンポ補正)
(1) トラック別に処理
from music21 import midi
mf = midi.MidiFile()
mf.open(input_midi)
mf.read()
mf.close()
for i, track in enumerate(mf.tracks):
print(f"Track {i} has {len(track.events)} events")
(2) 拍子・テンポを取得
for msg in mf.tracks[0].events:
if msg.isMetaEvent() and msg.type == "TIME_SIGNATURE":
print("Time Signature:", msg.numerator, "/", msg.denominator)
if msg.isMetaEvent() and msg.type == "SET_TEMPO":
print("Tempo:", 60_000_000 / msg.data) # microsec/beat → BPM
(3) ノートを時間に変換してCSV化
import csv
with open("notes.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["Note", "StartTime(ticks)", "Duration(ticks)", "Velocity"])
for track in mf.tracks:
for e in track.events:
if e.isNoteOn():
writer.writerow([e.pitch, e.time, e.duration, e.velocity])
【第4章 MusicXMLとPDF出力】
1. MusicXMLとは
MusicXMLは楽譜情報を記述するためのXMLベースの形式で、
MuseScore・Finale・Sibeliusなど全ての主要ソフトで互換性があります。
<note>
<pitch><step>C</step><octave>4</octave></pitch>
<duration>1</duration>
<type>quarter</type>
</note>
Pythonで生成した output.xml は、そのままMuseScoreで開けます。
2. PDFにするには
MuseScoreやLilyPondでMusicXMLを開き、
「ファイル → エクスポート → PDF」で印刷用の譜面を作成できます。
【第5章 音楽的な補正(Quantization)】
MIDIは人間の演奏ゆれを含むため、譜面化前に**量子化処理(Quantize)**を行うのが一般的。
例:16分音符単位で丸める処理(Python擬似コード)
# 16分音符の単位時間
tick_unit = 120
for note in notes:
note.start = round(note.start / tick_unit) * tick_unit
note.duration = round(note.duration / tick_unit) * tick_unit
これにより拍ズレが修正され、きれいな譜面になります。
【第6章 応用:ピアノ譜・バンド譜・音ゲー譜面】
| 用途 | 特徴 | 使用ツール |
|---|---|---|
| ピアノ譜 | 左右パートをMIDIチャンネルで分離 | MuseScore / music21 |
| バンド譜 | 各楽器をトラック別に解析 | Reaper / Logic / Cubase + MusicXML |
| 音ゲー譜面 | ノート時間を判定ラインに変換 | Unity, UE5, Python自作スクリプト |
【まとめ】
| 段階 | 内容 | 推奨ツール |
|---|---|---|
| 入門 | MIDI → 譜面を自動変換 | MuseScore |
| 中級 | Pythonで自動解析・出力 | music21 |
| 上級 | 独自譜面エンジン開発 | partitura / pretty_midi |