🦜
GoでVOICEVOX_COREを利用するサンプル
この記事はGo 言語 Advent Calendar 2023のシリーズ1の19日目の記事です
関連プロジェクト
VOICEVOX_CORE
ebitengine/puregoでラップしたライブラリ
Windows11の場合の環境構築
git-bash
curl -LO https://github.com/VOICEVOX/voicevox_core/releases/download/0.15.0-preview.13/download-windows-x64.exe
download-windows-x64.exe --device cpu --version 0.15.0-preview.13
cp voicevox_core/onnxruntime.dll ./
go mod init nanoda-cli
サンプルコード
main.go
package main
import (
"flag"
"log"
"time"
"github.com/aethiopicuschan/nanoda"
"github.com/ebitengine/oto/v3"
"github.com/hajimehoshi/ebiten/v2/audio/wav"
)
var (
ActorID = 3
Speed = 1.0
Pitch = 0.0
)
func init() {
flag.IntVar(&ActorID, "actor", ActorID, "actor id")
flag.Float64Var(&Speed, "speed", Speed, "speed")
flag.Float64Var(&Pitch, "pitch", Pitch, "pitch")
flag.Parse()
}
func speech(ctx *oto.Context, s nanoda.Synthesizer, text string) error {
q, err := s.CreateAudioQuery(text, nanoda.StyleId(ActorID))
if err != nil {
return err
}
q.SpeedScale = 1.5
q.PitchScale = Pitch
w, err := s.Synthesis(q, nanoda.StyleId(ActorID))
if err != nil {
return err
}
defer w.Close()
decoded, err := wav.DecodeWithoutResampling(w)
if err != nil {
return err
}
p := ctx.NewPlayer(decoded)
p.Play()
for p.IsPlaying() {
time.Sleep(20 * time.Millisecond)
}
return nil
}
func main() {
v, err := nanoda.NewVoicevox(
"voicevox_core/voicevox_core.dll",
"voicevox_core/open_jtalk_dic_utf_8-1.11",
"voicevox_core/model")
if err != nil {
log.Fatal(err)
}
ctx, _, err := oto.NewContext(&oto.NewContextOptions{
SampleRate: 48000,
ChannelCount: 1,
Format: oto.FormatSignedInt16LE,
})
if err != nil {
log.Fatal(err)
}
s, err := v.NewSynthesizer()
if err != nil {
log.Fatal(err)
}
if err := s.LoadModelsFromStyleId(nanoda.StyleId(ActorID)); err != nil {
log.Fatal(err)
}
for _, v := range flag.Args() {
if err := speech(ctx, s, v); err != nil {
log.Fatal(err)
}
}
}
ビルド
go mod tidy
go build .
実行
./nanoda-cli -actor=6 -speed=1.2 3レフト 5ライト フィニッシュ!
しゃべるよ!
まとめ
- CGOレスでもTTSが作れる
- VOICEVOXが謳う、「中くらいの品質のTTS」をGoから利用できる
- Windows11の場合onnxruntime.dllが別にあって優先的に読ませるのにカレントフォルダに持ってくるっていうちょっと面倒なことがあります。
- macOSやLinuxもほぼ同様の手順でシンプルに動く。Linuxならcuda対応も選べる。
追記
上記面倒な点はDLLの優先読込先を指定することで解決できた。
やり方はこちら。
Discussion