(トラック数,最短音符数,音高数) のnumpy配列になってしまえば煮るなり焼くなりこっちのもの🤩 pic.twitter.com/7WfjuAQujI
— Kurene (@_kurene) 2021年3月28日
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データをあっという間にプロットできます。
若干処理が重いので、トラック数やプロットする時間区間には注意した方がよさそうです。
Technical Documentation — Pypianoroll documentation
参考ページ
Pypianorollの日本語の解説としては、以下の記事が詳しく,オススメです。
補足
今回のプロットで用いたデータは、以下のWebサイト様からお借りしました。