VOCALOIDで書き出したMIDIファイルを開くと落ちる
CreateVertexBufferを呼び出すとき、頂点バッファサイズをゼロで呼び出したため、 CreateVertexBufferが不正呼び出し(D3DERR_INVALIDCALL)で失敗した。
VOCALOID MIDIファイルは、通常のノートON/OFFイベントを含まない仕様らしい。 このためノート数ゼロで初期化処理が実行され、描画するノートがないのにバッファを確保しようとしてエラーとなった。 VOCALOID MIDIファイルに限らず、通常のMIDIファイルでも発生しうる。
ノートの数がゼロの場合は、頂点生成処理と描画処理をスキップし、正常終了するように修正する。
対策箇所 DXPrimitive::CreateVertexBuffer() DXPrimitive::CreateIndexBuffer() DXPrimitive::Draw() DXPrimitive::LockVertex() DXPrimitive::UnlockVertex() DXPrimitive::LockIndex() DXPrimitive::LockIndex() DXPrimitive::UnlockIndex()
今回の対策でVOCALOIDが出力するMIDIデータを演奏できるようになったわけではない。 アプリケーションエラーで落ちないように対策しただけである。
原因に記載したとおり、VOCALOID MIDIファイルは通常のノートON/OFFイベントを含まない。 よって普通のMIDIプレーヤーで再生しても音は鳴らない。
VOCALOID MIDIファイルの内容を分析した例を以下に示す(SMIDILib.dllを使用)。 データの先頭で、INIファイルっぽいパラメータ設定文字列がテキストイベントで登録されている。 その後は、曲の最後までコントロールチェンジ(NRPN)が続くだけである。
-------------------- File Header -------------------- Chunk Type : MThd Length : 6 Format : 1 nTracks : 2 Devision : 480 -------------------- Track No.0 -------------------- Chunk Type : MTrk Length : 44 Delta Time | Event 0 | Meta: status=FF type=03<Sequence/Track Name> size=12 data=[ 4D 61 73 74 65 72 20 54 72 61 63 6B ] 0 | Meta: status=FF type=51<Set Tempo> size=3 data=[ 07 A1 20 ] 0 | Meta: status=FF type=58<Time Signature> size=4 data=[ 04 02 18 08 ] 7680 | Meta: status=FF type=58<Time Signature> size=4 data=[ 03 02 18 08 ] 0 | Meta: status=FF type=2F<End of Track> size=0 data=[ ] -------------------- Track No.1 -------------------- Chunk Type : MTrk Length : 12757 Delta Time | Event 0 | Meta: status=FF type=03<Sequence/Track Name> size=6 data=[ 56 6F 69 63 65 31 ] 0 | Meta: status=FF type=01<Text Event> size=127 data=[ 44 4D 3A 30 30 30 30 3A 5B 43 6F 6D 6D 6F 6E 5D 0A 56 65 72 73 69 6F 6E 3D 44 53 42 33 30 31 0A 4E 61 6D 65 3D 56 6F 69 63 65 31 0A 43 6F 6C 6F 72 3D 31 38 31 2C 31 36 32 2C 31 32 33 0A 44 79 6E 61 6D 69 63 73 4D 6F 64 65 3D 31 0A 50 6C 61 79 4D 6F 64 65 3D 31 0A 5B 4D 61 73 74 65 72 5D 0A 50 72 65 4D 65 61 73 75 72 65 3D 34 0A 5B 4D 69 78 65 72 5D 0A 4D 61 73 74 65 72 46 65 64 ] 0 | Meta: status=FF type=01<Text Event> size=127 data=[ 44 4D 3A 30 30 30 31 3A 65 72 3D 30 0A 4D 61 73 74 65 72 50 61 6E 70 6F 74 3D 30 0A 4D 61 73 74 65 72 4D 75 74 65 3D 30 0A 4F 75 74 70 75 74 4D 6F 64 65 3D 30 0A 54 72 61 63 6B 73 3D 31 0A 46 65 64 65 72 30 3D 30 0A 50 61 6E 70 6F 74 30 3D 30 0A 4D 75 74 65 30 3D 30 0A 53 6F 6C 6F 30 3D 30 0A 5B 45 76 65 6E 74 4C 69 73 74 5D 0A 30 3D 49 44 23 30 30 30 30 0A 37 36 38 30 3D 49 44 ] 0 | Meta: status=FF type=01<Text Event> size=127 data=[ 44 4D 3A 30 30 30 32 3A 23 30 30 30 31 0A 38 31 36 30 3D 49 44 23 30 30 30 32 0A 38 36 34 30 3D 49 44 23 30 30 30 33 0A 39 31 32 30 3D 49 44 23 30 30 30 34 0A 39 36 30 30 3D 49 44 23 30 30 30 35 0A 31 30 30 38 30 3D 49 44 23 30 30 30 36 0A 31 30 35 36 30 3D 49 44 23 30 30 30 37 0A 31 31 30 34 30 3D 49 44 23 30 30 30 38 0A 31 31 35 32 30 3D 49 44 23 30 30 30 39 0A 31 32 30 30 30 ] 0 | Meta: status=FF type=01<Text Event> size=127 data=[ 44 4D 3A 30 30 30 33 3A 3D 49 44 23 30 30 31 30 0A 31 33 34 34 30 3D 49 44 23 30 30 31 31 0A 31 33 39 32 30 3D 49 44 23 30 30 31 32 0A 31 34 34 30 30 3D 49 44 23 30 30 31 33 0A 31 34 38 38 30 3D 49 44 23 30 30 31 34 0A 31 35 33 36 30 3D 49 44 23 30 30 31 35 0A 31 35 38 34 30 3D 49 44 23 30 30 31 36 0A 31 36 33 32 30 3D 49 44 23 30 30 31 37 0A 31 36 38 30 30 3D 49 44 23 30 30 31 ] ★曲先頭にテキストイベントが大量に格納されている・・・ 0 | MIDI: ch.0 cmd=<Control Change> data=[ B0 63 60 ] 0 | MIDI: ch.0 cmd=<Control Change> data=[ B0 62 00 ] 0 | MIDI: ch.0 cmd=<Control Change> data=[ B0 06 00 ] 0 | MIDI: ch.0 cmd=<Control Change> data=[ B0 26 00 ] ★曲の終了までNRPNだけが続く・・・
VOCALOID Editorで「ファイル」→「書き出し」→「VOCALOID MIDI」を選択して出力した VOCALOID MIDIファイル(*.mid)を読み込むと、次のエラーが発生して落ちる。