こんにちは!仙台高専プログラミング部(広瀬) のはちもりと申します。
VOICEVOX歌唱APIが好きなので記事を書きます。
以前こちらの記事で、VOICEVOX歌唱APIの仕様と、C++ライブラリ「Siv3D」で使う方法を書きました。
今回の記事の内容は、「楽譜の作成方法」 だけなので、他の情報をお求めの方は、上記の記事も参考にしてみてください!👍
楽譜とは?
VOICEVOX歌唱APIは、簡単に言うと、「楽譜ファイルを渡すと、歌声を生成して音声ファイルを返してくれる」 というAPIです。
その楽譜はVOICEVOX独自のJSONの形式で用意する必要があります。
こちらが、ドレミ~と歌う例です↓
{
"notes": [
{
"frame_length": 2,
"key": null,
"lyric": ""
},
{
"frame_length": 47,
"key": 60,
"lyric": "ド"
},
{
"frame_length": 47,
"key": 62,
"lyric": "レ"
},
{
"frame_length": 94,
"key": 64,
"lyric": "ミ"
}
{
"frame_length": 2,
"key": null,
"lyric": ""
},
]
}
ステップ1:音符
これら1つずつの要素が、1音符のデータになります。
{
"frame_length": 47,
"key": 60,
"lyric": "ド"
}
ステップ2:休符
これは、とても短い長さの休符を表しています。
楽譜全体の最初と最後に置くといい感じになるので、とりあえず置いています。
(音符の長さを変えれば、通常の休符としての使い方もできます)
{
"frame_length": 2,
"key": null,
"lyric": ""
}
ステップ3:音符の長さ
frame_length
は音符の長さを表しています。この例だと47フレームです。
"frame_length": 47
算出方法は以下の通りです。
frame_length = ( 音符の秒数 × BPM × 93.75 ) を整数に丸めた値
ステップ4:音の高さ
key
は音の高さをMIDI番号で表しています。この例だと 60 = ド(C4) です。
"key": 60
ステップ5:歌詞
lyric
は音符の歌詞を表しています。
カタカナもしくはひらがなをパラメータとして与えます。
1音符に1モーラまでしか入れられないことに注意してください。
"lyric": "ド"
楽譜の作成方法
楽譜ファイルを準備するために、他の形式の楽譜ファイルから変換して作成することが考えられます。
今回は、VOICEVOXのプロジェクトファイル.vvproj
から、VOICEVOX歌唱APIの仕様に合ったJSONへ変換することを考えます。VOICEVOX上で動かせる楽譜であれば、歌唱APIでも動かせるからです。
.vvproj
もJSON形式で書かれていますが、楽譜の記述形式が違います。
//省略
"notes": [
{
"id": "77b5e49d-09e7-4eba-8ea4-ebc71fab5794",
"position": 0,
"duration": 480,
"noteNumber": 60,
"lyric": "ド"
},
{
"id": "5b1a39fa-203b-465d-a9c4-40bb2db1ecb0",
"position": 480,
"duration": 480,
"noteNumber": 62,
"lyric": "レ"
},
{
"id": "b75f29cb-3575-47b3-9369-4e048111f4ba",
"position": 960,
"duration": 960,
"noteNumber": 64,
"lyric": "ミ"
}
]
//省略
ここで、"noteNumber": 60,"lyric": "ド"
は、それぞれ歌唱APIのkey
とlyric
に対応しています。
一方、"duration": 480
は480 tickを表していて、frame_length
とは単位が違います。
tick とは?
tick は「MIDI 楽譜で使われる最小単位」です。
例:tpqn(Ticks Per Quarter Note) = 480
なら 1つの 四分音符 = 480 tick となります。
tick → frame_length の変換手順
-
tick → 拍数
beats = ticks / tpqn
-
拍数 → 秒数
seconds = beats × (60 / BPM)
-
秒数 → フレーム数 (VOICEVOX は 93.75 fps)
frame_length = ( seconds × 93.75 )
を整数に丸めた値
↑整数に丸めているので、丸め誤差が発生します。
これが積み重なると、想定していたBPMからずれた楽譜になってしまう場合があります。
そこで、キャリー処理を入れる必要があります。
誤差補正
丸める前の ( seconds × 93.75 )
に対し、小数部の誤差を変数に溜めておき、
次の音符へ「お釣り」のように受け渡す方法を使います。
具体的には、四捨五入で生じた累積誤差が 1 frame 以上になった瞬間にまとめて ±1 frame を加減して帳尻を合わせます。
これでテンポずれが解決できます!
(VOIECVOX Discord鯖の技術相談チャンネルでの会話を参考にさせていただきました🙇)
自動変換ツール
ChatGPTに手伝ってもらったら簡単にできました!2種類あります。
C++だけ多少わかるので、オフライン版を先に作りました。
WEB版の方は、オフライン版をもとにしてAIに全部書かせたので、何もわからないです!!!たすけて!!!
使い方
【オフライン版】
- アプリを起動します。(DLはここから)
-
🎵 入力ファイルを選択
ボタンをクリックして.vvproj
ファイルを選択します。 -
📂 出力フォルダを選択
ボタンをクリックして出力先のフォルダを指定します。 -
✅ 変換
ボタンをクリックすると、選択された.vvproj
ファイルが VOICEVOX の歌唱API仕様に対応した.json
に変換され、出力先フォルダに保存されます。
【WEB版】
- ブラウザでページを開きます。
-
ファイルを選択
ボタンをクリックして、.vvproj
ファイルを選択します。 - ファイルが選択されると 「変換してダウンロード」 ボタンが有効になります。
- 「変換してダウンロード」 をクリックすると、選択された
.vvproj
ファイルが VOICEVOX の歌唱API仕様に対応した.json
に変換され、ダウンロードされます。
まとめ
VOICEVOX歌唱APIが好きなので、もっと多くの人に使ってほしいと願っています!
以上で終わります!ありがとうございました。