🎧

VoiceVoxで高クオリティな音声合成をかんたんに行う

2022/02/17に公開
古い記事

こんにちは。
今回はとっても高クオリティかつ可愛らしい音声合成が行えるvoicevoxを使ってみます。

voicevox とは

高品質な音声合成ソフト

無料で使える中品質なテキスト読み上げソフトウェア、VOICEVOXのエディター

と、書かれていますが、正直中品質なんてもんじゃあありません。
めちゃくちゃ高品質です。
サンプルは下記リンクから聞けます。
https://voicevox.hiroshiba.jp/

かんたんに使える

デスクトップ環境ではGUIでかんたんに音声合成が可能です。

また、voicevox-engineというapiサーバーが公開されているのでhttpリクエストを送るだけでかんたんに音声合成が可能です。
Dockerイメージも公開されているので手軽に起動できます。
Discordの音声読み上げBotなんかもこれでかんたんに作れます。

使ってみる

今回はDockerとNodeJsを使って音声を合成してみます。

Dockerでエンジンを起動

今回はdocker-composeを使ってエンジンを起動します。

docker-compose.yml
version: "2"
services:
  voicevox_engine:
    # CPUの場合は hiroshiba/voicevox_engine:cpu-ubuntu20.04 を使用
    image: hiroshiba/voicevox_engine:nvidia-ubuntu20.04-latest
    ports:
      - "50021:50021"
    tty: true
    #
    # 以下の項目はCPUの場合はなくても大丈夫
    #
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu] 

docker-compose.ymlを保存したら実行。

docker-compose up

結構不安定で起動に失敗することがあります。
ubuntu18.04版もあるのでそちらを使うのもありかも。

コードを書く

環境

  • NodeJS v17
  • yarn v3.1.0
  • typescript v4.5.5

モジュール

voicevox-engine用のモジュールを作成したのでよければ使ってください。

  • voicevox-api-client v1.0.0

書く

https://voicevox.github.io/voicevox_engine/api/
apiドキュメントがあるのでこちらでより詳しい内容を確認できます。

とりあえず全体のコードを。

index.ts
import { Client } from 'voicevox-api-client'
import fs from 'fs'

const client = new Client('http://localhost:50021')

const createVoice = async (text: string) => {
  const query = await client.query.createQuery(0, text)
  const voice = await client.voice.createVoice(0, query)
  const buf = Buffer.from(voice)
  fs.writeFileSync('voice.wav', buf)
}

createVoice("Dockerがどっかーん")

順番に説明していきます。


まず一番上のほう。
書いてあることそのまんまです。
モジュールからClientをインポートしてインスタンスを作成しています。
ここのURLは先程作成したvoicevox-engineのサーバーのURLにしてください。

index.ts
import { Client } from 'voicevox-api-client'
import fs from 'fs'

const client = new Client('http://localhost:50021')

次に一番大事なcreateVoice関数。
まず文字列からqueryを作成します。
次に作成したqueryを音声に変換します。
voiceに音声のarrayBufferが入るのでBufferに変換してファイルに書き出します。
めちゃめちゃかんたんです。

index.ts
const createVoice = async (text: string) => {
  const query = await client.query.createQuery(0, text)
  const voice = await client.voice.createVoice(0, query)
  const buf = Buffer.from(voice)
  fs.writeFileSync('voice.wav', buf)
}

Discussion