« 「著作権の効力の制限」を考えてみる #3 | トップページ | 初音ミクに喋らせてみた(Perl版012) »

初音ミクに喋らせてみた(Perl版011)

Perl で漢字仮名混じり文から、VSQファイルを自動生成させてみました。形態素解析にはMecabを使用しています。Mecabは、自然文の読みまでを出力してくれるので、音声合成に楽に適用できます。
ここで、Mecab の設計者およびプログラマの方々に感謝いたします。

ミクに喋らせる文章は、特許法1条 「この法律は、発明の保護及び利用を図ることにより、発明を奨励し、もつて産業の発達に寄与することを目的とする。」 です。

「test_miku011.mp3」をダウンロード

「test_miku011.vsq」をダウンロード

今回は、アクセントっぽいのも入れてあります。あくまでテスト用の仮コーディングであり、標準語のアクセントではありません。

ソースコードはこちらです、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 );
}

|

« 「著作権の効力の制限」を考えてみる #3 | トップページ | 初音ミクに喋らせてみた(Perl版012) »

初音ミク」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: 初音ミクに喋らせてみた(Perl版011):

» 「初音ミクのお父さん」インタビューを読んだ [CloseBox and OpenPod]
 初音ミクにおける天馬博士みたいな存在、VOCALOID開発者であるの剣持秀紀の [続きを読む]

受信: 2007年12月27日 (木) 00時05分

« 「著作権の効力の制限」を考えてみる #3 | トップページ | 初音ミクに喋らせてみた(Perl版012) »