【第9回MMD杯本選】シャオシャオ通りの物語はぜんぶほんとだよ? 【MMDFes】
あと4ヶ月でクリスマスですね。
www.py - WAVEファイルから MMD の首振り回転モーション作成 - つちのこ、のこのこ。(はてな番外地) で配布しているスクリプト貼っておきます。
付属のモデルと説明が無いと使いようがないと思いますが参考として。
u'''www - WAVEファイルから MMD の首振り回転モーション作成 Python 2.6.6 ''' from __future__ import division import math import wave import struct import os __author__ = 'kadotanimitsuru' __credits__ = '' __date__ = '2012-07-25' __version__ = '1.0.0' #################### ここを書き換える #################### VOICELIST = ( # 変換する音声ファイル名, 秒あたりの回転速度 (u'sora.WAV', 1/3), (u'yukari.WAV', 1/3), (u'iroha.WAV', 1/3), (u'kiyoteru.WAV', 1), (u'yuki.WAV', 1), ) ######################################################## FPS = 30 # 秒間フレーム数 AMPLITUDE = 40 # 振幅の倍率 INTERPOLATION_CURVE = ( u'20,20,107,107,20,20,107,107,20,20,107,107,20,20,107,107') # 補完曲線 class Wavedata(object): def __init__(self, filename): self.file = wave.open(filename, 'rb') (self.nchannels, sampwidth, self.framerate, self.nframes, comptype, compname) = self.file.getparams() if sampwidth != 2: raise ValueError('Not corresponded to the sample size %d bit.' % sampwidth * 8) self.ended = False def waves(self, ms, l): p = self.framerate * ms // 1000 if p < 0 or p >= self.nframes: f = [] if p >= self.nframes: self.ended = True else: rl = min(l, self.nframes - p) self.file.setpos(p) f = list(struct.unpack( '<%dh' % (rl * self.nchannels), self.file.readframes(rl))) if self.nchannels == 1: return (f + [0] * (l - len(f)),) elif self.nchannels == 2: L = [f[i] for i in xrange(0, len(f), 2)] R = [f[i] for i in xrange(1, len(f), 2)] return (L + [0] * (l - len(L)), R + [0] * (l - len(R))) else: raise ValueError('Not corresponded to the channels size %d.' % self.nchannels) def volume(self, ms): f = self.waves(ms, self.framerate // FPS) return max((sum(abs(x) for x in i) // len(i) for i in f)) def www(filename, speed=1): w = Wavedata(filename) datalist = [] ms = 0 while not w.ended: v = w.volume(ms) ang = (speed * math.pi * 2 * ms / 1000) datalist.append(( (v / 0x8000), (math.degrees(ang) % 360 - 180))) ms += 1000 / FPS return datalist def main(voicelist): for filename, speed in voicelist: datalist = www(filename, speed) savename = filename.split('.')[0] + '.csv' print u'"%s" (%d flames)' % (savename, len(datalist)) data = [] for n, (v, r) in enumerate(datalist): if n % 2: v = -v data.append( (u'%d,首,0,0,0,%.3f,%.3f,0,' % (n, v * AMPLITUDE, r)) + INTERPOLATION_CURVE) fulldata = u'''Vocaloid Motion Data 0002 アクセ回転補助 Motion,bone,x,y,z,rx,ry,rz,x_p1x,x_p1y,x_p2x,x_p2y,y_p1x,y_p1y,y_p2x,y_p2y,z_p1x,z_p1y,z_p2x,z_p2y,r_p1x,r_p1y,r_p2x,r_p2y %s Expression,name,fact Camera,d,a,x,y,z,rx,ry,rz,x_p1x,x_p1y,x_p2x,x_p2y,y_p1x,y_p1y,y_p2x,y_p2y,z_p1x,z_p1y,z_p2x,z_p2y,r_p1x,r_p1y,r_p2x,r_p2y,d_p1x,d_p1y,d_p2x,d_p2y,a_p1x,a_p1y,a_p2x,a_p2y Light,r,g,b,x,y,z ''' % '\n'.join(data) with open(savename, 'w') as f: f.write(fulldata.encode('cp932')) if __name__=='__main__': main(VOICELIST) # Copyright: This module has been placed in the public domain. # パブリックドメイン。好きに流用してください。