RubyからVOICEVOXを使って合成音声を生成する
合成音声を生成したい
Discord向けの読み上げBotを作るときに、RubyからVOICEVOXという音声合成ツールを操作したくなったので、メモがてら記します。
やる
環境
- OS: Debian 11.8
- Ruby: 3.2.2
- その他: Dockerコンテナ下
開発環境であるcode-serverのコンテナ内で動作確認をしています。
VOICEVOXをCLIで動かす
依存関係解決
curl, p7zipやlibsndfileが必要なためインストールします。
sudo apt install -y curl p7zip libsndfile1
インストール
VOICEVOXをインストールしているけど、GUIは使わないのでVOICEVOX ENGINEだけでもいいかも。
それこそ、Dockerコンテナ建てれるなら、Dockerイメージ使っちゃうのもあり。
以下のコマンドを実行すると、カレントディレクトリに「squashfs-root」というフォルダーが生成される。 その中の、「run」を実行するとHTTPサーバーが建ち、VOICEVOXを使えるっぽい。
curl -s https://voicevox.hiroshiba.jp/static/fc70af03e46d5bd83329e61236a9cd3d/linuxInstallCpu.sh | bash
~/.VOICEVOX.AppImage --appimage-extract
実行
./squashfs-root/run
を実行することでVOICEVOX ENGINEが起動します。
50021番ポートで待ち受けしているようで、ここにHTTPリクエストを投げてあげることで音声が合成できるようです。
VOICEVOX ENGINE の方にcURLを使用したサンプルコードがありますので、試してみるのも良いでしょう。
Rubyで音声合成
- 「http://127.0.0.1:50021/audio_query」のURLクエリにspaekerとtextを指定し、POSTすると合成音声に必要なJSONが返ります。
- speaker: 数値で指定。ずんだもんなら1、四国めたんなら2など
- text: 喋らせる文書。URLエンコードをする必要がある。
- 「http://127.0.0.1:50021/synthesis」のURLクエリにspeaker、リクエストボディには先ほどのJSONを指定し、POSTするとWAVが返ります。
voicevox.rb
# frozen_string_literal: true
require 'net/http'
require 'uri'
# VoiceVoxとやり取りするためのクラス
class VoiceVox
def initialize
@host = 'http://127.0.0.1:50021'
end
# textとspeakerから音声を生成
def speak(text, speaker = 1)
query = voice_query(text, speaker)
generate_voice(query, speaker)
end
private
# VoiceVoxのクエリを作成
def voice_query(text, speaker)
response = post_req('/audio_query', { speaker: speaker, text: text })
response.body
end
# クエリから音声を生成
def generate_voice(query, speaker)
response = post_req('/synthesis', { speaker: speaker }, query)
response.body
end
# Post送信用関数
def post_req(endpoint, query, data = '')
uri = URI.join(@host, endpoint)
uri.query = URI.encode_www_form(query)
header = { 'Content-Type' => 'application/json' }
Net::HTTP.post(uri, data, header)
end
end
main.rb
# frozen_string_literal: true
require_relative 'voicevox.rb'
vb = VoiceVox.new
sound = vb.speak('本日は晴天なり。', 1)
# 保存
File.open('test.wav', 'w') do |file|
file.write(sound)
end
という2つのファイルを作成し、main.rbを実行することで、test.wavが生成されます。
audio_query
、synthesis
の両方ともにPOSTリクエストをしなければならず、audio_query
はURLクエリ、synthesis
はURLクエリ及びリクエストボディを指定する必要があります。
なお、Content-Typeはどちらもapplication/json
を受け付けるため、audio_query
には空のリクエストボディを指定しています。
詳細なドキュメントはvoicevox_engine API Documentにまとめられていますので、こちらを参照ください。
おわり
Linuxでも動かせる数少ない音声合成ツールなのでとてもありがたいです・・・。(ボイロは窓だけやしね)
今回使用したのはCPU版とのことで、nVidia GPU対応版を使用するともっと高速に生成することができるらしいです。
音声合成についても、もう少し調整できる部分やユーザー辞書などの機能があるらしく今作ってるBotがその域に達したら触ってみようかなと思います。
追伸
書いてから気づいたけどvoicevox.rbという非公式ラッパーあったわ。
これならHTTPリクエスト使わずともいけるかも(まあええか