「VSQのファイル仕様(推定)」の編集履歴(バックアップ)一覧に戻る
VSQのファイル仕様(推定) - (2010/05/04 (火) 13:35:42) のソース
*&color(blue){このページについて} &color(red){&bold(){更新中です}} VOCALOID2 Editor(以下Editorと略)が使用するシーケンスファイル(拡張子.vsq)のファイル仕様について書きます。 管理人の推測によるものなので、正確さを欠く箇所があることを最初にお断りしておきます。 *&color(blue){vsqファイルの概要} Standard Midi File (SMF)のFormat 1仕様に準拠しているようです。数値の格納はビッグエンディアン。SMFの仕様についてはこのページでは省略します。 *&color(blue){トラックの種類} Format 1のSMFファイルにはトラックを分割して格納することができますが、vsqファイルは2種類のトラックを区別して使用しているようです。 **①テンポ、拍子を格納したトラック #divclass(bo01){ -トラック名が必ず"Master Track"となります。 -含まれるのは以下のメタイベントのみ。 --Sequence/Track Name(0xff 0x03 [length] [text]) --End of Track(0xff 0x2f 0x00) --Set Tempo(0xff 0x51 0x03 [tempo(3bytes)]) --Time Signature(0xff 0x58 0x04 + 4bytes) -必ずSMFのヘッダの直後に表れ、vsqファイルに1個のみ。 -テンポの変更は②のメタテキストには記入されず、このトラックのSet Tempoメタイベントを用いて記録される -拍子の変更も、同様にTIme Signatureメタイベントを用いて記録される } **②Editorのピアノロール画面の情報を格納したトラック #divclass(bo01){ -トラック名が、Editorのトラック名と一致します。 -必ず上記のMaster Trackの直後に表れます -Editorに必要な情報は全て(恐らく)メタテキストで記述されます -上記メタテキストの日本語部分はShift-JISエンコードになっている -上記メタテキストは全てDelta-time=0として記述されます -メタテキストの直後にはMIDI Eventのコントロールチェンジが記述されます。(確認したものは全てNRPN[Non Registered Parameter Number]を用いたコントロールチェンジ) -メタテキストは複数に分割して記述されます。 -メタテキストの文字列のバイト数は、末尾の物を除き全て127byte(0x7f)となる。末尾の最後のメタテキストのデータ長は127byte以下。 -分割されているメタテキストを繋げると、1個のテキストファイルになる。元のテキストファイルの改行は0x0aに置き換えられる。 -上から数えてN番目のメタテキストは、"DM:" + N.ToString( "0000" ) + ":" という感じのプレフィクスが付く。 -プレフィクスの番号(DM:****の****)は4桁ごとに増える。つまり、DM:9999の次はDM:00010000。 -Editorのトラックの数だけvsqファイルに記述される。 -&color(orange){todo:文字列長が127byteでないメタテキストが現れた場合、Editorはどう処理するのか?} -&color(orange){todo:メタテキストが"DM:****"の数字の順番に表れなかったときのEditorの挙動} -&color(orange){todo:改行は0x0aで表されているが、0x0d 0x0aとしても正しく処理されるのか?} } *&color(blue){NRPNによるコントロールチェンジの意味は?} -VOCALOID2 Editorのヘルプファイルに各NRPNの意味の一覧あり。 -Note Duration(0x50 0x04)の情報はメタテキストには直接記述されないが、メタテキストの情報から計算可能。 #divclass(bo01){{ $$NoteDuration=\left[\frac{125 \cdot clocks}{tempo}\right]$$ &italic(){clocks}: 音符の長さ(クロック) &italic(){tempo}: テンポ(125等、実際にvsqに保存されるテンポの値は$$6\times10^7 / tempo$$) nは0以上の値となる。[]はガウスの記号。 }} -[[NRPNに記録されるクロックと「プリセンドタイム」]] *&color(blue){各トラックのメタテキストの中身} -メタテキストを順番どおりに(DM:****の****部分の数字の順)につなげる事で得られる。 -書式は、INIファイルと同じ。セクション([]でくくられて記録される部分)には次の種類がある。 --[Common] --[Master] --[Mixer] --[EventList] --[PitchBendBPList] --[PitchBendSensBPList] --[DynamicsBPList] --[EpRResidualBPList] --[EpRESlopeBPList] --[EpRESlopeDepthBPList] --[EpRSineBPList] --[Reso1FreqBPList] --[Reso2FreqBPList] --[Reso3FreqBPList] --[Reso4FreqBPList] --[Reso1BWBPList] --[Reso2BWBPList] --[Reso3BWBPList] --[Reso4BWBPList] --[Reso1AmpBPList] --[Reso2AmpBPList] --[Reso3AmpBPList] --[Reso4AmpBPList] --[GenderFactorBPList] --[PortamentoTimingBPList] --[VibTremDepthBPList] --[OpeningBPList] --[ID#****] ---****は4桁の整数。[ID#9999]の次は[ID#10000]。 --[h#****] ---****は4桁の整数。[h#9999]の次は[h#10000]。 *&color(blue){各セクションに記録される内容} **[Common] #divclass(bo01){ >[Common] >Version=DSB202 >Name=Voice2 (1) >Color=157,181,123 >DynamicsMode=0 >PlayMode=1 :Version|ボカロのバージョン。例えばMEIKOならDSB202、MIKUならDSB301 :Name|トラック名 :Color|意味不明 :DynamicsMode|Dynamicsカーブを表示するモード(Expert)なら1、しない(Standard)なら0。VOCALOID2の場合は1で固定。 :PlayMode|Play With Synthesisなら1、Play After Synthesiなら0、Offなら-1。VOCALOID2の場合、0は1と見なされる。 } **[Master] **[Mixer] **[EventList] #divclass(bo01){{ >0=ID#0000 >1920=ID#0001 上記のように、「クロック」=「イベントのID」という書式で各時刻に起こるイベントを列挙する。同じ時刻に2つ以上のイベントが起こる場合、「クロック」=「イベント1のID」,「イベント2のID」とコンマ区切りで1行に記述する。 }} **[PitchBendBPList] -PIT(ピッチベンド)カーブ。 **[PitchBendSensBPList] -PBS(ピッチベンドセンシティビティ)カーブ **[DynamicsBPList] -DYN(ダイナミクス)カーブ **[EpRResidualBPList] -VOCALOID2の場合、BRE(ブレシネス)カーブ。VOCALOID1の場合、Noiseカーブ。 **[EpRESlopeBPList] -BRI(ブライトネス)カーブ **[EpRESlopeDepthBPList] -CLE(クリアネス)カーブ **[EpRSineBPList] -Harmonicsカーブ(VOCALOID1のみ) **[Reso1FreqBPList] **[Reso2FreqBPList] **[Reso3FreqBPList] **[Reso4FreqBPList] **[Reso1BWBPList] **[Reso2BWBPList] **[Reso3BWBPList] **[Reso4BWBPList] **[Reso1AmpBPList] **[Reso2AmpBPList] **[Reso3AmpBPList] **[Reso4AmpBPList] **[VibTremDepthBPList] -Effect2 Depthカーブ(VOCALOID1のみ) **[GenderFactorBPList] -GEN(ジェンダーファクター)カーブ **[PortamentoTimingBPList] -POR(ポルタメントタイミング)カーブ **[OpeningBPList] -OPE(オープニング)カーブ **[ID#****] #divclass(bo01){ -音符または歌手のプロパティが記述される ***音符の場合 #divclass(bo01){ 例えば次の内容が記述される >[ID#0001] >Type=Anote >Length=240 >Note#=60 >Dynamics=64 >PMBendDepth=8 >PMBendLength=0 >PMbPortamentoUse=3 >DEMdecGainRate=50 >DEMaccent=50 >LyricHandle=h#0001 >NoteHeadHandle=#h0002 #divclass(bo01){ :Type=Anote|音符を表すIDであることを示す :Length=240|長さが240クロックの音符 :Note#=60|音の高さは60(60=C3) :Dynamics=64|ベロシティ(VEL)の値 :PMBendDepth=8|「音符のプロパティ」の「ベンドの深さ」(VOCALOID2のみ) :PMBendLength=0|「音符のプロパティ」の「ベンドの長さ」(VOCALOID2のみ) :PMbPortamentoUse=3|「音符のプロパティ」の「~形でポルタメントを付加」の指定内容。「上行形で~」が指定されていれば値は+1、「下行形で~」が指定されていれば値は+2。即ちこの場合は両方が指定されている。(VOCALOID2のみ) :DEMdecGainRate=50|「音符のプロパティ」の「ディケイ」(VOCALOID2のみ) :DEMaccend=50|「音符のプロパティ」の「アクセント」(VOCALOID2のみ) :LyricHandle=h#0001|この音符が使用する歌詞情報 :NoteHeadHandle=h#0002|この音符が使用するアタック情報(VOCALOID1のみ) } } } **[h#****] #divclass(bo01){ -歌詞/ビブラート/歌手/アタックのいずれかのプロパティが記述される。 ***「歌詞」の場合 #divclass(bo01){ >Lx=[歌詞],[発音記号],[歌詞Delta],[ConsonantAdjustment]×発音記号の個数,[プロテクトフラグ] #divclass(bo01){ :Lx|このハンドルが表す歌詞の単位(0 <= x <= 音符のクロック数-1)。VOCALOID2の場合L0のみが現れる。VOCALOID1の場合、複数の歌詞単位を入力するとL1以降に記録される。 :歌詞|前後に引用符(")の付いた歌詞を表す文字列。引用符そのものは引用符2つ("")で表現される。 :発音記号|文字列。発音記号が半角スペース区切りで記録される。 :歌詞Delta|実数。第x番目の歌詞単位の、音符全体の長さに対する相対長さ。L0~Lxまでの歌詞Deltaを合算すると1になる。 :ConsonantAdjustment|整数。子音なら64、母音なら0、識別できない(VOCALOID2の規格にない)発音記号なら0。NRPNのMSB0x50 LSB0x11~0x21のData LSBに記録される値(Consonant Adjustment n)と同じ値。 :プロテクトフラグ|整数。「歌詞のプロパティ」の「プロテクト」がチェックされていれば1、そうでなければ0. } -発音記号の個数&br()NRPNには先頭の16個までしか記録されないが、こっちにはかなりの個数発音記号を入力できてしまう。少なくとも「a」7630個までは入力でき、waveへのレンダリングも出来た(ただし先頭の16個しか発音されない模様)。 -Lxのxの最大値が「音符全体の長さ-1」になっている理由。1個の歌詞単位の最小長さは1クロックで、1未満の実数にはできないから。 } ***「ビブラート」の場合 #divclass(bo01){ >IconID=$04040004 >IDS=normal >Caption= >Original=5 >Length=120 >StartDepth=64 >DepthBPNum=3 >DepthBPX=0.500000,0.750000,1.000000 >DepthBPY=64,32,0 >StartRate=64 >RateBPNum=3 >RateBPX=0.500000,0.750000,1.000000 >RateBPY=64,32,0 #divclass(bo01){ :IconID|ビブラートの形式を識別するID :IDS|不明(解析中、「normal」、「extreme」、「slight」等が入る) :Caption|不明(解析中) :Original|不明(解析中) :Length|ビブラートの長さ(クロック単位) :StartDepth|振幅の開始値 :DepthBPNum|振幅カーブのデータ点数。これが0のとき、DepthBPXとDepthBPYは省略される :DepthBPX|振幅カーブのデータ点(時間軸)。DepthBPNum個の値が、コンマ区切りで列挙される。0.0がビブラート開始時刻を、1.0がビブラート終了時刻を表す :DepthBPY|振幅カーブのデータ点 :StartRate|周期の開始値 :RateBPNum|周期カーブのデータ点数。これが0のとき、RateBPXとRateBPYは省略される :RateBPX|周期カーブのデータ点(時間軸)。書式と値の意味はDepthBPXに同じ :RateBPY|周期カーブのデータ点 } -VOCALOIDシステムの表情ライブラリ(のビブラート)のどれと関連付けられるかを特定するために,IconID,IDSが使われる.ライブラリ内に「IDS」と同じ名前のものが唯一つ存在すれば,それがそのまま使用される.この場合,IconIDがでたらめでも正しく認識される.ライブラリ内に「IDS」と同じ名前のものが2つ以上存在する場合は,IconIDの下4桁($04040001なら"0001")を元に検索が行われる. } ***「歌手のプロパティ」の場合 #divclass(bo01){ >IconID=$07010002 >IDS=Miku3 >Original=2 >Caption= >Length=1 >Language=0 >Program=2 } #divclass(bo01){{ :IconID|言語・プログラムチェンジを識別するID。"$0701"の部分は固定で、下4桁のうち最初の2桁が歌唱言語、最後の2桁がプログラムチェンジを表す。いずれも16進数で表現される。例えば「初音ミク(日本語)、プログラムチェンジ2」の場合$07010002、「巡音ルカ(英語)、プログラムチェンジ0」の場合$07010100となる。 :IDS|Singer Editorで設定した歌手の名前 :Original|(Lanuage << 8) | Program :Caption|謎の空文字列 :Length|謎の整数 :Language|歌唱言語を表すインデクス。(日本語が0、英語が1) :Program|Singer Editorで設定した「プログラムチェンジ」の値 }} ***「アタックのプロパティ」の場合(VOCALOID1のみ) #divclass(bo01){ >IconID=$01010002 >IDS=accent >Original=2 >Caption=Accent >Length=120 >Duration=64 >Depth=64 } #divclass(bo01){{ :IconID| :IDS| :Original| :Caption| :Length|120固定のようだ :Duration| }} } ----