vsqx2midi.py - VOCALOID3 の vsqx を MIDI ファイルに変換する
テンポやら何やら全部無視して、単にノートとペロシティだけを MIDI にするやっつけ Python スクリプトですが、参考までに。
実行するには Python 2.6 あるいはそれ以降のバージョンの Python 2.x を用意してください。*1
使い方
- Python をインストール(やり方は適当にぐぐって)
- 下のソースを BOM付き utf-8 で「vsqx2midi.py」という名前で保存 (メモ帳で文字コード「utf-8」にして保存すればOK)
- そのファイルを右クリックして「Edit with IDLE」を選択
- VOCALOID3 Editor で適当な曲を「hoge.vsqx」という名前で保存
- IDLE で [F5] を押して Python スクリプトを実行
- 「hoge.mid」という名前で MIDI の出来上がり
# 2012-01-03 ver.1.0.1 トラックが16を超える場合への対処を追加 import xml.dom.minidom import struct FILENAME = 'hoge.vsqx' # 対象のファイル名 def chrs(s): return ''.join([chr(x) for x in s]) def i2(v): if v > 0xffff: raise ValueError(v) return struct.pack('>H', v) def i4(v): if v > 0xffffffff: raise ValueError(v) return struct.pack('>I', v) def delta(v): a = [] while True: if v <= 0x7f: a.append(v) break else: a.append(v % 0x80) v //= 0x80 a.reverse() return ''.join([chr(x + 0x80) for x in a[0:-1]] + [chr(a[-1])]) def notedata(n, tag): return n.getElementsByTagName(tag)[0].firstChild.data def makenote(n): return dict([(x, notedata(n, x)) for x in ('posTick', 'durTick', 'noteNum', 'velocity', 'lyric', 'phnms')]) def noteon(ch, nn, vel): return chr(0x90 + ch) + chr(nn) + chr(vel) def noteoff(ch, nn): return chr(0x80 + ch) + chr(nn) + chr(0) def maketrack(n): track = [] if n.nodeName == 'note': track.append(makenote(n)) if n.childNodes: for i in n.childNodes: track += maketrack(i) return track def makemiditrack(n, ch): ch %= 16 # 16トラックを超えたら 0 に戻る midi = [] tick = 0 for i in maketrack(n): t = int(i['posTick']) notelen = int(i['durTick']) midi.append( delta(t - tick) + noteon(ch, int(i['noteNum']), int(i['velocity'])) + delta(notelen) + noteoff(ch, int(i['noteNum']))) tick = t + notelen data = ''.join(midi) + delta(0) + chrs([0xff, 0x2f, 0]) return 'MTrk' + i4(len(data)) + data def makemidifile(filename): print 'loading:', filename d = xml.dom.minidom.parse(filename) tracks = [] for n, i in enumerate(d.getElementsByTagName('vsTrack')): print 'track', n tracks.append(makemiditrack(i, n)) header = 'MThd' + i4(6) + i2(1) + i2(len(tracks)) + i2(480) return header + ''.join(tracks) m = makemidifile(FILENAME) f = open('hoge.mid', 'wb') f.write(m) f.close() ## パブリックドメイン。好きに流用してください
普通は必要ないプログラムかと思いますが、ついうっかり VOCALOID3 Editor で直接打ち込みしてしまい、MIDI ファイルが無い、という場合には使えるかも?
*1:2.6 以前でも OK かもしれませんが、作ったのが 2.6 なので