Wizard Notes

Python, JavaScript を使った音楽信号分析の技術録、作曲活動に関する雑記

Python: pypianorollを使ってMIDIデータをNumpy配列に変換し、マルチトラックをプロット

MIDI形式のデータは演奏の操作・記録方式として優れていますが、データ分析やプログラム上での編集は割と面倒です。

音響信号のようにN次元配列にデータを格納できれば非常に楽なのですが、MIDIの仕様を理解して、ノートの発音タイミングを時間解像度で補正したりしつつ集計するのはなかなか大変です。

今回ご紹介する Pypianoroll は、MIDIのようなマルチトラックピアノロールデータを効率的に扱うことを目的としたPythonモジュールであり、

MIDIデータとNumpy配列/NPZファイルの相互的な変換や、読み書きに対応しています。

Pypianoroll — Pypianoroll documentation

Hao-Wen Dong, Wen-Yi Hsiao, and Yi-Hsuan Yang, “Pypianoroll: Open Source Python Package for Handling Multitrack Pianorolls,” ISMIR2018.

https://salu133445.github.io/pypianoroll/pdf/pypianoroll-ismir2018-lbd-poster.pdf

Pypianorollにはたくさんの便利な機能がありますが、単純にMIDI形式のデータをNumpy配列に変換するだけなら、以下のように僅か数行で書くことができます。

import pypianoroll

filepath = "your_midi_data.mid"
# resolution: 四分音符ごとのタイムステップ数
# Return type: ndarray, shape=(?, ?, 128)
multitrack = pypianoroll.read(filepath, resolution=24)
multitrack_numpy = multitrack.stack()

戻り値は、(トラック数,最短音符数,音高数)である3次元のndarray (3階テンソル)となっています。

filepath = "Caccini_avemaria_orche.mid"
>>> multitrack_numpy.shape
(4, 7080, 128)

また、メタ情報(例:テンポ)に関する情報はMultitrackクラスのメンバ変数に格納されています。

pprint(multitrack)
Multitrack(name=None, resolution=24, tempo=array(shape=(7080, 1), dtype=float64), downbeat=array(shape=(7080, 1), dtype=bool), tracks=[StandardTrack(name=' Grand Piano *merged', program=46, is_drum=False, pianoroll=array(shape=(7080, 128), dtype=uint8)), StandardTrack(name=' Strings *merged', program=48, is_drum=False, pianoroll=array(shape=(7080, 128), dtype=uint8)), StandardTrack(name=' Oboe *merged', program=68, is_drum=False, pianoroll=array(shape=(7080, 128), dtype=uint8)), StandardTrack(name=' Flute *merged', program=73, is_drum=False, pianoroll=array(shape=(7080, 128), dtype=uint8))])

Pypianoroll Classes — Pypianoroll documentation

なお、ビジュアライゼーションも簡単にできます。

例えば、

import matplotlib.pyplot as plt

multitrack.plot()
plt.show()

と書けば、マルチトラックのMIDIデータをあっという間にプロットできます。

若干処理が重いので、トラック数やプロットする時間区間には注意した方がよさそうです。

f:id:Kurene:20210330225530p:plain

Technical Documentation — Pypianoroll documentation

参考ページ

Pypianorollの日本語の解説としては、以下の記事が詳しく,オススメです。

aws.amazon.com

補足

今回のプロットで用いたデータは、以下のWebサイト様からお借りしました。

クラシック MIDI ラインムジーク ~調和のひととき~