🦜

GoでVOICEVOX_COREを利用するサンプル

2023/12/20に公開

この記事はGo 言語 Advent Calendar 2023のシリーズ1の19日目の記事です

関連プロジェクト

VOICEVOX_CORE
https://github.com/VOICEVOX/voicevox_core

ebitengine/puregoでラップしたライブラリ
https://github.com/aethiopicuschan/nanoda

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の優先読込先を指定することで解決できた。
やり方はこちら。

https://zenn.dev/link/comments/313573ed05b8b5

Discussion