cadencii_jp @ wiki

メニュー

トップページ
ブログ
.NETライブラリ
アプリケーション
ドキュメント





更新履歴

「VSQのファイル仕様(推定)」の編集履歴(バックアップ)一覧はこちら

VSQのファイル仕様(推定)」の最新版変更点

追加された行はこの色になります。

削除された行はこの色になります。

 *&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|
 }}
 
 }
 
 ----