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で音声合成
- speaker: 数値で指定。ずんだもんなら1、四国めたんなら2など
 - text: 喋らせる文書。URLエンコードをする必要がある。
 
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リクエスト使わずともいけるかも(まあええか
  ぶ!ログ