現在進行中、おーぷんMIDIぷろじぇくと、 MIDIData の Python ラッパー作成
くずさんのおーぷんMIDIプロジェクト 、 MIDIDataライブラリの Python ラッパーをつくりはじめた。現在 MIDIIO.dll の公開関数を ctypes でラップし終えたところ。
- (オリジナルの使用方法)(C言語、MIDIDataライブラリ 公式ガイドブックより)
#include <stdio.h> #include <MIDIData.h> int main () { char szBuf[1024]; MIDIData* pMIDIData; MIDITrack* pMIDITrack; MIDIEvent* pMIDIEvent; /* MIDIデータをスタンダードMIDIファイル(*.mid)から読み込む */ pMIDIData = MIDIData_LoadFromSMF ("chocho.mid"); if (pMIDIData == NULL) { printf ("MIDIファイルが開けません。\n"); return 0; } /* MIDIデータのプロパティを出力する。*/ printf ("[MIDIデータ]\n"); printf ("フォーマット=%d\n", MIDIData_GetFormat (pMIDIData)); printf ("トラック数=%d\n", MIDIData_GetNumTrack (pMIDIData)); printf ("タイムモード=%d\n", MIDIData_GetTimeMode (pMIDIData)); printf ("タイムレゾリューション=%d\n", MIDIData_GetTimeResolution (pMIDIData)); /* それぞれのトラックについて */ forEachTrack (pMIDIData, pMIDITrack) { printf ("[MIDIトラック]\n"); printf ("小節:拍:ティック 種類 長さ 内容\n"); /* それぞれのイベントについて */ forEachEvent (pMIDITrack, pMIDIEvent) { printf ("%s\n", MIDIEvent_ToString (pMIDIEvent, szBuf, sizeof(szBuf))); } } /* MIDIデータをメモリ上から削除する */ MIDIData_Delete (pMIDIData); return 1; }
- Python ラッパー完成予想図。こんなふうにかけるようになるといいなぁ。
# coding: utf-8 from mididata import mididata def main(): try: # MIDIデータをスタンダードMIDIファイル(*.mid)から読み込む data = mididata.LoadFromSMF('chocho.mid') try: # MIDIデータのプロパティを出力する print u'[MIDIデータ]' print u'フォーマット=%d' % data.Format print u'トラック数=%d' % data.NumTrack print u'タイムモード=%d' % data.TimeMode print u'タイムレゾリューション=%d' % data.TimeResolution # それぞれのトラックについて for track in data.iter_tracks(): print u'[MIDIトラック]' print u'小節:拍:ティック 種類 長さ 内容' # それぞれのイベントについて for event in track.iter_events(): print event.ToString() except MididataError: u'操作中に異常が発生しました' finally: # MIDIデータをメモリ上から削除する #(明示的に削除しなくとも自動で消える) data.Delete() except MididataError: print u'ファイルが開けませんでした' if __name__ == '__main__': main()
- 現状…。これは使いづらい。薄いラッパーができただけなのだから、当然こうなるわな。 C とくらべても try, finally 文でデリート処理が書きやすいという程度の利点しかない。 char szBuf[1024]; のかわりに buf = create_string_buffer(1024) とか書かないといけないから楽になっていないし。 forEach 系マクロがない分、むしろ悪化している。
# coding: utf-8 u"""おーぷんMIDIぷろじぇくと MIDIData つかってみる """ from ctypes import * from mididata import mididata, miditrack, midievent def main(): # MIDIデータをスタンダードMIDIファイル(*.mid)から読み込む data = mididata.LoadFromSMF('chocho.mid') if data: try: # MIDIデータのプロパティを出力する print u'[MIDIデータ]' print u'フォーマット=%d' % mididata.GetFormat(data) print u'トラック数=%d' % mididata.GetNumTrack(data) print u'タイムモード=%d' % mididata.GetTimeMode(data) print u'タイムレゾリューション=%d' % mididata.GetTimeResolution( data) buf = create_string_buffer(1024) # それぞれのトラックについて track = mididata.GetFirstTrack(data) while track: print u'[MIDIトラック]' print u'小節:拍:ティック 種類 長さ 内容' # それぞれのイベントについて event = miditrack.GetFirstEvent(track) while event: print midievent.ToString(event, buf, 1024) event = midievent.GetNextEvent(event) track = miditrack.GetNextTrack(track) finally: # MIDIデータをメモリ上から削除する mididata.Delete(data) else: print u'Openエラー' if __name__ == '__main__': main()
これからが本番。現在の mididata, miditrack, midievent モジュールを _mididata, _miditrack, _midievent に改名して裏側に追いやり、より Python っぽいライブラリでラップする。完成にはまだまだかかりそう。