初音ミクに喋らせてみた(Perl版011)
Perl で漢字仮名混じり文から、VSQファイルを自動生成させてみました。形態素解析にはMecabを使用しています。Mecabは、自然文の読みまでを出力してくれるので、音声合成に楽に適用できます。
ここで、Mecab の設計者およびプログラマの方々に感謝いたします。
ミクに喋らせる文章は、特許法1条 「この法律は、発明の保護及び利用を図ることにより、発明を奨励し、もつて産業の発達に寄与することを目的とする。」 です。
今回は、アクセントっぽいのも入れてあります。あくまでテスト用の仮コーディングであり、標準語のアクセントではありません。
ソースコードはこちらです、UTF8の文字コードでセーブしてください。
#!/Perl
########################################################################
# miku_talk ver.0.1.1
#
# Programmed by Akira Izumi
# Ver.0.0.1:ハードコーディング"みく" ... 6/Dec/2007
# Ver.0.0.4:任意の平仮名入力を受付ける...15/Dec/2007
# Ver.0.1.1:ソースをUTF8化し、形態素解析Mecabを組込...26/Dec/2007
#
use MIDI;
use Encode;
use MeCab;
use strict;
use warnings;
# my $myTalk = "発明とは、自然法則を利用した技術的思想の創作のうち高度のものをいう。";
my $myTalk = "この法律は、発明の保護及び利用を図ることにより、発明を奨励し、もつて産業の発達に寄与することを目的とする。";
miku_VsqGenerate($myTalk,"test_miku011.vsq");
exit(0);
########################################################################
#
# サブルーチン名:miku_VsqGenerate
#
# 日本語文字列からVSQファイルを生成する
# 第1引数:漢字仮名交じりのテキスト文字列
# 第2引数:出力VSQファイル名
#
#
sub miku_VsqGenerate {
my $myTalk = $_[0];
my $myVsqFile = $_[1];
#
# マスタートラックのイベント定義。
#
my @masterEvents = (
['track_name', 0, 'Master Track'],
['set_tempo', 0, 500_000], # 1qn = .50 seconds
['time_signature',0,4,2,24,8 ],
['end_track' , 0],
);
#
# 平仮名からミク発音記号への変換ハッシュ表
#
my %phonetic = (
"あ"=>"a", "い"=>"i", "う"=>"M", "え"=>"e", "お"=>"o",
"か"=>"k a","き"=>"k' i","く"=>"k M", "け"=>"k e", "こ"=>"k o",
"さ"=>"s a","し"=>"S i", "す"=>"s M", "せ"=>"s e", "そ"=>"s o",
"た"=>"t a","ち"=>"tS i","つ"=>"ts M", "て"=>"t e", "と"=>"t o",
"な"=>"n a","に"=>"J i", "ぬ"=>"n M", "ね"=>"n e", "の"=>"n o",
"は"=>"h a","ひ"=>"C i", "ふ"=>"p\\ M","へ"=>"h e", "ほ"=>"h o",
"ま"=>"m a","み"=>"m' i","む"=>"m M", "め"=>"m e", "も"=>"m o",
"や"=>"j a", "ゆ"=>"j M", "いぇ"=>"j e","よ"=>"j o",
"ら"=>"4 a","り"=>"4' i","る"=>"4 M", "れ"=>"4 e", "ろ"=>"4 o",
"わ"=>"w a","ゐ"=>"w i",
# "ゑ"=>"w e",
"を"=>"o","うぃ"=>"w i", "うぇ"=>"w e",
"ん"=>"n",
#"んが"=>"N a", "んぎ"=>"N i", "んぐ"=>"N M", "んげ"=>"N e", "んご"=>"N o",
#"んにゃ"=>"N' a","んにぃ"=>"N' i","んにゅ"=>"N' M","んにぇ"=>"N' e","んにょ"=>"N' o",
"が"=>"g a", "ぎ"=>"g' i", "ぐ"=>"g M", "げ"=>"g e", "ご"=>"g o",
"ざ"=>"dz a", "じ"=>"dZ i", "ず"=>"dz M", "ぜ"=>"dz e", "ぞ"=>"dz o",
"だ"=>"d a", "ぢ"=>"dZ i", "づ"=>"dz M", "で"=>"d e", "ど"=>"d o",
"ば"=>"b a", "び"=>"b' i", "ぶ"=>"b M", "べ"=>"b e", "ぼ"=>"b o",
"ぱ"=>"p a", "ぴ"=>"p' i", "ぷ"=>"p M", "ぺ"=>"p e", "ぽ"=>"p o",
"きゃ"=>"k' a","きぃ"=>"k' i","きゅ"=>"k' M","きぇ"=>"k' e","きょ"=>"k' o",
"しゃ"=>"S a", "しぃ"=>"S i", "しゅ"=>"S M", "しぇ"=>"S e", "しょ"=>"S o",
"ちゃ"=>"tS a","ちぃ"=>"tS i","ちゅ"=>"tS M","ちぇ"=>"tS e","ちょ"=>"tS o",
"にゃ"=>"J a", "にぃ"=>"J i", "にゅ"=>"J M", "にぇ"=>"J e", "にょ"=>"J o",
"ひゃ"=>"C a", "ひぃ"=>"C i", "ひゅ"=>"C M", "ひぇ"=>"C e", "ひょ"=>"C o",
"ふゃ"=>"p\\' a","ふぃ"=>"p\\' i","ふゅ"=>"p\\' M","ふぇ"=>"p\\' e","ふょ"=>"p\\' o",
"みゃ"=>"m' a","みぃ"=>"m' i","みゅ"=>"m' M","みぇ"=>"m' e","みょ"=>"m' o",
"りゃ"=>"4' a","りぃ"=>"4' i","りゅ"=>"4' M","りぇ"=>"4' e","りょ"=>"4' o",
"ぎゃ"=>"g' a","ぎぃ"=>"g' i","ぎゅ"=>"g' M","ぎぇ"=>"g' e","ぎょ"=>"g' o",
"じゃ"=>"Z a", "じぃ"=>"Z i", "じゅ"=>"Z M", "じぇ"=>"Z e", "じょ"=>"Z o",
"じゃ"=>"dZ a","じぃ"=>"dZ i","じゅ"=>"dZ M","じぇ"=>"dZ e","じょ"=>"dZ o",
"ぢゃ"=>"dZ a","ぢぃ"=>"dZ i","ぢゅ"=>"dZ M","ぢぇ"=>"dZ e","ぢょ"=>"dZ o",
"びゃ"=>"b' a","びぃ"=>"b' i","びゅ"=>"b' M","びぇ"=>"b' e","びょ"=>"b' o",
"ぴゃ"=>"p' a","ぴぃ"=>"p' i","ぴゅ"=>"p' M","ぴぇ"=>"p' e","ぴょ"=>"p' o",
"ふぁ"=>"p\\ a","ふぃ"=>"p\\ i","ふぅ"=>"p\\ M","ふぇ"=>"p\\ e","ふぉ"=>"p\\ o",
"てゃ"=>"t' a","てぃ"=>"t' i","てゅ"=>"t' M","てぇ"=>"t' e","てょ"=>"t' o",
"でゃ"=>"d' a","でぃ"=>"d' i","でゅ"=>"d' M","でぇ"=>"d' e","でょ"=>"d' o",
"ぁ"=>"h\\ a", "ぃ"=>"h\\ i", "ぅ"=>"h\\ M","ぇ"=>"h\\ e", "ぉ"=>"h\\ o",
"っ"=>"tS ",
"すぃ"=>"s i", "ずぃ"=>"dz i", "とぅ"=>"t M","どぅ"=>"d M",
"ア"=>"a", "イ"=>"i", "ウ"=>"M", "エ"=>"e", "オ"=>"o",
"カ"=>"k a","キ"=>"k' i","ク"=>"k M", "ケ"=>"k e", "コ"=>"k o",
"サ"=>"s a","シ"=>"S i", "ス"=>"s M", "セ"=>"s e", "ソ"=>"s o",
"タ"=>"t a","チ"=>"tS i","ツ"=>"ts M", "テ"=>"t e", "ト"=>"t o",
"ナ"=>"n a","ニ"=>"J i", "ヌ"=>"n M", "ネ"=>"n e", "ノ"=>"n o",
"ハ"=>"h a","ヒ"=>"C i", "フ"=>"p\\ M","ヘ"=>"h e", "ホ"=>"h o",
"マ"=>"m a","ミ"=>"m' i","ム"=>"m M", "メ"=>"m e", "モ"=>"m o",
"ヤ"=>"j a", "ユ"=>"j M", "イェ"=>"j e","ヨ"=>"j o",
"ラ"=>"4 a","リ"=>"4' i","ル"=>"4 M", "レ"=>"4 e", "ロ"=>"4 o",
"ワ"=>"w a","ヰ"=>"w i",
# "ヱ"=>"w e",
"ヲ"=>"o",
"ウィ"=>"w i", "ウェ"=>"w e",
"ン" =>"n",
#"ンガ" =>"N a", "ンギ"=>"N i", "ング"=>"N M", "ンゲ"=>"N e", "ンゴ"=>"N o",
#"ンニャ"=>"N' a","ンニィ"=>"N' i","ンニュ"=>"N' M","ンニェ"=>"N' e","ンニョ"=>"N' o",
"ガ"=>"g a", "ギ"=>"g' i", "グ"=>"g M", "ゲ"=>"g e", "ゴ"=>"g o",
"ザ"=>"dz a", "ジ"=>"dZ i", "ズ"=>"dz M", "ゼ"=>"dz e", "ゾ"=>"dz o",
"ダ"=>"d a", "ヂ"=>"dZ i", "ヅ"=>"dz M", "デ"=>"d e", "ド"=>"d o",
"バ"=>"b a", "ビ"=>"b' i", "ブ"=>"b M", "ベ"=>"b e", "ボ"=>"b o",
"パ"=>"p a", "ピ"=>"p' i", "プ"=>"p M", "ペ"=>"p e", "ポ"=>"p o",
# "ヴ"=>""p M",
"キャ"=>"k' a","キィ"=>"k' i","キュ"=>"k' M","キェ"=>"k' e","キョ"=>"k' o",
"シャ"=>"S a", "シィ"=>"S i", "シュ"=>"S M", "シェ"=>"S e", "ショ"=>"S o",
"チャ"=>"tS a","チィ"=>"tS i","チュ"=>"tS M","チェ"=>"tS e","チョ"=>"tS o",
"ニャ"=>"J a", "ニィ"=>"J i", "ニュ"=>"J M", "ニェ"=>"J e", "ニョ"=>"J o",
"ヒャ"=>"C a", "ヒィ"=>"C i", "ヒュ"=>"C M", "ヒェ"=>"C e", "ヒョ"=>"C o",
"フャ"=>"p\\' a","フィ"=>"p\\' i","フュ"=>"p\\' M","フェ"=>"p\\' e","フョ"=>"p\\' o",
"ミャ"=>"m' a", "ミィ"=>"m' i", "ミュ"=>"m' M", "ミェ"=>"m' e", "ミョ"=>"m' o",
"リャ"=>"4' a", "リィ"=>"4' i", "リュ"=>"4' M", "リェ"=>"4' e", "リョ"=>"4' o",
"ギャ"=>"g' a","ギィ"=>"g' i","ギュ"=>"g' M","ギェ"=>"g' e","ギョ"=>"g' o",
"ジャ"=>"Z a", "ジィ"=>"Z i", "ジュ"=>"Z M", "ジェ"=>"Z e", "ジョ"=>"Z o",
"ジャ"=>"dZ a","ジィ"=>"dZ i","ジュ"=>"dZ M","ジェ"=>"dZ e","ジョ"=>"dZ o",
"ヂャ"=>"dZ a","ヂィ"=>"dZ i","ヂュ"=>"dZ M","ビェ"=>"dZ e","ビョ"=>"dZ o",
"ビャ"=>"b' a","ビィ"=>"b' i","ビュ"=>"b' M","ビェ"=>"b' e","ビョ"=>"b' o",
"ピャ"=>"p' a","ピィ"=>"p' i","ピュ"=>"p' M","ピェ"=>"p' e","ピョ"=>"p' o",
"ファ"=>"p\\ a","フィ"=>"p\\ i","フゥ"=>"p\\ M","フェ"=>"p\\ e","フォ"=>"p\\ o",
"テャ"=>"t' a", "ティ"=>"t' i", "テゥ"=>"t' M", "テェ"=>"t' e", "テォ"=>"t' o",
"デャ"=>"d' a", "ディ"=>"d' i", "デゥ"=>"d' M","デェ"=>"d' e", "デォ"=>"d' o",
"ァ"=>"h\\ a", "ィ"=>"h\\ i", "ゥ"=>"h\\ M", "ェ"=>"h\\ e", "ォ"=>"h\\ o",
"ッ"=>"tS ",
"スィ"=>"s i", "ズィ"=>"dz i", "トゥ"=>"t M","ドゥ"=>"d M");
#
my %phonetic_class = (
"ー"=>"長音",
"-"=>"長音",
"-"=>"長音"
);
#
# ミクの発音用テキストに於ける初期値の設定。
#
my @myCommonSection =();
push @myCommonSection, "[Common]";
push @myCommonSection, "Version=DSB301";
push @myCommonSection, "Name=Voice1";
push @myCommonSection, "Color=181,162,123";
push @myCommonSection, "DynamicsMode=1";
push @myCommonSection, "PlayMode=1";
my @myMasterSection =();
push @myMasterSection, "[Master]";
push @myMasterSection, "PreMeasure=4";
my @myMixerSection =();
push @myMixerSection, "[Mixer]";
push @myMixerSection, "MasterFeder=0";
push @myMixerSection, "MasterPanpot=0";
push @myMixerSection, "MasterMute=0";
push @myMixerSection, "OutputMode=0";
push @myMixerSection, "Tracks=1";
push @myMixerSection, "Feder0=0";
push @myMixerSection, "Panpot0=0";
push @myMixerSection, "Mute0=0";
push @myMixerSection, "Solo0=0";
my @myEventListSection =();
push @myEventListSection, "[EventList]";
push @myEventListSection, "0=ID#0000";
my @myIDSection =();
push @myIDSection, "[ID#0000]";
push @myIDSection, "Type=Singer";
push @myIDSection, "IconHandle=h#0000";
my @myHandleSection =();
push @myHandleSection, "[h#0000]";
push @myHandleSection, "IconID=\$07010000";
push @myHandleSection, "IDS=Miku";
push @myHandleSection, "Original=0";
push @myHandleSection, "Caption=";
push @myHandleSection, "Length=1";
push @myHandleSection, "Language=0";
push @myHandleSection, "Program=0";
my @mikuMidiEvents = ();
push @mikuMidiEvents,['control_change' , 0, 0, 99, 96];
push @mikuMidiEvents,['control_change' , 0, 0, 98, 0];
push @mikuMidiEvents,['control_change' , 0, 0, 6, 0];
push @mikuMidiEvents,['control_change' , 0, 0, 38, 0];
push @mikuMidiEvents,['control_change' , 0, 0, 98, 1];
push @mikuMidiEvents,['control_change' , 0, 0, 6, 0];
push @mikuMidiEvents,['control_change' , 0, 0, 38, 0];
push @mikuMidiEvents,['control_change' , 0, 0, 98, 2];
push @mikuMidiEvents,['control_change' , 0, 0, 6, 0];
push @mikuMidiEvents,['control_change' , 0, 0, 99, 83];
push @mikuMidiEvents,['control_change' , 0, 0, 98, 2];
push @mikuMidiEvents,['control_change' , 0, 0, 6, 0];
#
# ミク発音(平仮名)を、ミク発音用メタデータに変換し、
# 同時にMIDIイベントを生成する。
#
my $i=0;
my $pitch = 180;
my $note = 64;
my $myIdPos = 7680;
my $myIdPosLast = $myIdPos;
my $myHinsiLast = "";
Encode::from_to($myTalk,"UTF8","shiftjis");
my $mecab = MeCab::Tagger->new();
my $node = $mecab->parseToNode($myTalk);
for( ; $node; $node = $node->{next} ) {
next unless defined $node->{surface};
my $midasi = $node->{surface};
my( $hinsi, $yomi ) = (split( /,/, $node->{feature} ))[0,8];
if( $hinsi eq "BOS/EOS" ) {
next;
}
print $midasi, "\t<", $yomi, ">\t", $hinsi, "\n";
#
# 文節の区切りを判断して、発音間隔を空ける
# アクセント($note) は仮
#
Encode::from_to($hinsi,"shiftjis","UTF8");
if( ( $hinsi eq "名詞" || $hinsi eq "動詞" || $hinsi eq "形容詞" || $hinsi eq "形容動詞" )
&& ($myHinsiLast eq "助詞" || $myHinsiLast eq "接続詞" || $myHinsiLast eq "記号") ) {
$myIdPos += $pitch;
$note = 64;
}
if( $hinsi eq "記号" ) {
$note = 64;
}
my $idxLyric = 0;
my $j=0;
for($j=0; $idxLyric<length($yomi); $j++,$i++) {
my $myLyricLen = 6;
my $myLyric = "";
my $myLyric_utf8 = "";
my $myPhonetic = "";
for($myLyricLen=6; $myLyricLen>0; $myLyricLen-=2) {
$myLyric_utf8 = $myLyric = substr($yomi,$idxLyric,$myLyricLen);
Encode::from_to($myLyric_utf8,"shiftjis","UTF8");
$myPhonetic = $phonetic{$myLyric_utf8};
if( defined($myPhonetic) || $myLyricLen==2 ) {
last;
}
}
$idxLyric += $myLyricLen;
my $myLength = $pitch;
if( $idxLyric + 2 <= length($yomi) ){
$myLyric_utf8 = substr($yomi,$idxLyric,2);
Encode::from_to($myLyric_utf8,"shiftjis","UTF8");
if( $myLyric_utf8 eq "ー" ) {
$myLength += $pitch;
$idxLyric += 2;
}
}
if( defined($myPhonetic)) {
push @myEventListSection, sprintf("%d=ID#%04d",$myIdPos,$i+1);
push @myIDSection, sprintf("[ID#%04d]",$i+1);
push @myIDSection, "Type=Anote";
push @myIDSection, "Length=".$myLength;
push @myIDSection, "Note#=".$note;
push @myIDSection, "Dynamics=64";
push @myIDSection, "PMBendDepth=20";
push @myIDSection, "PMBendLength=0";
push @myIDSection, "PMbPortamentoUse=0";
push @myIDSection, "DEMdecGainRate=50";
push @myIDSection, "DEMaccent=50";
push @myIDSection, sprintf("LyricHandle=h#%04d",$i+1);
push @myHandleSection, sprintf("[h#%04d]",$i+1);
push @myHandleSection, "L0=\"".$myLyric."\",\"". $myPhonetic."\",1.000000,64,0,0";
$myIdPos += $myLength;
# print "L0=\"".$myLyric."\",\"". $myPhonetic."\",1.000000,64,0,0","\n";
if( $i==0 ) {
push @mikuMidiEvents,['control_change', 5760, 0, 99, 80];
} else {
push @mikuMidiEvents,['control_change', $myIdPos - $myIdPosLast, 0, 99, 80];
}
push @mikuMidiEvents,['control_change', 0, 0, 98, 0];
push @mikuMidiEvents,['control_change', 0, 0, 6, 0];
push @mikuMidiEvents,['control_change', 0, 0, 38, 0];
push @mikuMidiEvents,['control_change', 0, 0, 98, 1];
push @mikuMidiEvents,['control_change', 0, 0, 6, 15];
push @mikuMidiEvents,['control_change', 0, 0, 38, 80];
push @mikuMidiEvents,['control_change', 0, 0, 98, 2];
push @mikuMidiEvents,['control_change', 0, 0, 6, 64];
push @mikuMidiEvents,['control_change', 0, 0, 98, 3];
push @mikuMidiEvents,['control_change', 0, 0, 6, 64];
push @mikuMidiEvents,['control_change', 0, 0, 98, 4];
push @mikuMidiEvents,['control_change', 0, 0, 6, 1];
push @mikuMidiEvents,['control_change', 0, 0, 38, 122];
push @mikuMidiEvents,['control_change', 0, 0, 98, 5];
push @mikuMidiEvents,['control_change', 0, 0, 6, 1];
push @mikuMidiEvents,['control_change', 0, 0, 98, 18];
push @mikuMidiEvents,['control_change', 0, 0, 6, 3];
push @mikuMidiEvents,['control_change', 0, 0, 98, 19];
push @mikuMidiEvents,['control_change', 0, 0, 6, 109];
push @mikuMidiEvents,['control_change', 0, 0, 38, 64];
push @mikuMidiEvents,['control_change', 0, 0, 98, 20];
push @mikuMidiEvents,['control_change', 0, 0, 6, 39];
push @mikuMidiEvents,['control_change', 0, 0, 98, 21];
push @mikuMidiEvents,['control_change', 0, 0, 6, 105];
push @mikuMidiEvents,['control_change', 0, 0, 38, 0];
push @mikuMidiEvents,['control_change', 0, 0, 98, 79];
push @mikuMidiEvents,['control_change', 0, 0, 6, 127];
push @mikuMidiEvents,['control_change', 0, 0, 98, 80];
push @mikuMidiEvents,['control_change', 0, 0, 6, 12];
push @mikuMidiEvents,['control_change', 0, 0, 98, 81];
push @mikuMidiEvents,['control_change', 0, 0, 6, 8];
push @mikuMidiEvents,['control_change', 0, 0, 98, 82];
push @mikuMidiEvents,['control_change', 0, 0, 6, 20];
push @mikuMidiEvents,['control_change', 0, 0, 98, 83];
push @mikuMidiEvents,['control_change', 0, 0, 6, 28];
push @mikuMidiEvents,['control_change', 0, 0, 98, 84];
push @mikuMidiEvents,['control_change', 0, 0, 6, 24];
push @mikuMidiEvents,['control_change', 0, 0, 98, 85];
push @mikuMidiEvents,['control_change', 0, 0, 6, 10];
push @mikuMidiEvents,['control_change', 0, 0, 98, 86];
push @mikuMidiEvents,['control_change', 0, 0, 6, 12];
push @mikuMidiEvents,['control_change', 0, 0, 98, 87];
push @mikuMidiEvents,['control_change', 0, 0, 6, 12];
push @mikuMidiEvents,['control_change', 0, 0, 98, 88];
push @mikuMidiEvents,['control_change', 0, 0, 6, 0];
push @mikuMidiEvents,['control_change', 0, 0, 98, 89];
push @mikuMidiEvents,['control_change', 0, 0, 6, 50];
push @mikuMidiEvents,['control_change', 0, 0, 98, 90];
push @mikuMidiEvents,['control_change', 0, 0, 6, 50];
push @mikuMidiEvents,['control_change', 0, 0, 98, 127];
push @mikuMidiEvents,['control_change', 0, 0, 6, 127];
$myIdPosLast = $myIdPos;
} else {
$myIdPos += $myLength;
# print "No Phonetic\n";
}
if($note == 64) {
$note = 65;
}
}
$myHinsiLast = $hinsi;
}
push @mikuMidiEvents,['end_track' , $pitch+1920];
push @myEventListSection, sprintf("%d=EOS",$i*$pitch+7620);
#
# ミク発音用メタデータのセクションを結合する
#
my $my_miku_phonetics="";
my $phonetic = "";
foreach $phonetic (@myCommonSection) {
$my_miku_phonetics = $my_miku_phonetics.$phonetic."\n";
}
foreach $phonetic (@myMasterSection) {
$my_miku_phonetics = $my_miku_phonetics.$phonetic."\n";
}
foreach $phonetic (@myMixerSection) {
$my_miku_phonetics = $my_miku_phonetics.$phonetic."\n";
}
foreach $phonetic (@myEventListSection) {
$my_miku_phonetics = $my_miku_phonetics.$phonetic."\n";
}
foreach $phonetic (@myIDSection) {
$my_miku_phonetics = $my_miku_phonetics.$phonetic."\n";
}
foreach $phonetic (@myHandleSection) {
$my_miku_phonetics = $my_miku_phonetics.$phonetic."\n";
}
#
# Voice1トラックのイベントを生成する。
#
my @voice1Events = (
['track_name', 0, 'Voice1'],
);
for($i=0; $i*119<length($my_miku_phonetics); $i++) {
push @voice1Events, ['text_event', 0,
sprintf("DM:%04d:",$i).substr($my_miku_phonetics,$i*119,119) ];
}
my $mikuMidi = "";
foreach $mikuMidi (@mikuMidiEvents) {
push @voice1Events,$mikuMidi;
}
#
# マスタートラックとVoice1トラックからVSQファイルを生成する。
#
my $master_track = MIDI::Track->new({ 'events' => \@masterEvents });
my $voice1_track = MIDI::Track->new({ 'events' => \@voice1Events });
my $opus = MIDI::Opus->new(
{ 'format' => 1, 'ticks' => 480, 'tracks' => [ $master_track, $voice1_track ] } );
$opus->write_to_file( $myVsqFile );
}
| 固定リンク
「初音ミク」カテゴリの記事
- MikuMikuTalk ver.0.2.1c(2012.04.20)
- MikuMikuTalk ver.0.2.1(2012.04.13)
- Tda式Appendミク・ver.βのMMM対応パッチ(2012.04.08)
- Tell Your World MMD-PV(2012.04.04)
- Tda式Appendミクさんの物理演算対応(2012.02.22)
この記事へのコメントは終了しました。
コメント