ゆっくりボイス : AquesTalk 2 を C# から呼び出してみる
今度は AquesTalk 2 系を触るよ。
前回の記事で AquesTalk 1 系の DLL を呼び出せたので、今度は AquesTalk 2 系を呼び出してみる。
v1 系との大きな違いは、v1 系は声質ごとに DLL ファイルが存在していたのに対し、v2 系では DLL ファイルは単一で、声質のデータ (.phont
) ファイルを別途読み込んで使うという形式になっている点。
ライブラリを用意する
善良な市民は、公式から評価版のライブラリをダウンロードしよう。
aqtk2-win-eva_230.zip
を解凍し、lib/AquesTalk2.dll
(本体 DLL) と、phont/
配下のテキトーな .phont
ファイルを1つ取得しておこう。以降のコード例では phont/aq_f1c.phont
を使う前提とする。
評価版を回避したい人は、SofTalk に同梱されている DLL と .phont
ファイルを流用しても動かせた (自己責任で)。
- SofTalk ディレクトリ配下の
dll/aqt2/AquesTalk2.dll
- SofTalk ディレクトリ配下の
dll/aqt2/phont/aq_f1c.phont
(任意の.phont
ファイル)
C# コードを書く
取得した AquesTalk2.dll
と .phont
ファイルと同じディレクトリに、C# ソースファイルを作って実装していく。
atk2.cs
using System; // Console
using System.IO; // MemoryStream
using System.Media; // SoundPlayer
using System.Runtime.InteropServices; // Marshal
public class ATK2 {
// DLL ファイルのパス
const string dllPath = ".\\AquesTalk2.dll";
// 声質の定義ファイルのパス
const string filePath = ".\\aq_f1c.phont";
[DllImport(dllPath)]
private static extern IntPtr AquesTalk2_Synthe(string koe, int iSpeed, ref int size, byte[] phontDat);
// phont ファイルを使用せず DLL 内蔵の音質だけ使う場合は
// 以下のように「byte[] phontDat」部分を「int phontDat」と宣言し引数に 0 を与えて呼び出せば良い
//private static extern IntPtr AquesTalk2_Synthe(string koe, int iSpeed, ref int size, int phontDat);
[DllImport(dllPath)]
private static extern void AquesTalk2_FreeWave(IntPtr wavPtr);
public static void Main() {
Console.WriteLine("Start");
const int iSpeed = 100;
const string koe = "こんにちわバージョンつー";
Console.WriteLine("DLL : {0}", dllPath);
Console.WriteLine("Speed : {0}", iSpeed);
Console.WriteLine("Text : {0}", koe);
// phont ファイルを読み込む
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[fs.Length];
int bytesRead = fs.Read(buffer, 0, buffer.Length);
fs.Close();
// 音声ファイルとしてそのまま保存可能なバイト列の先頭ポイントを取得する
int size = 0;
IntPtr wavPtr = IntPtr.Zero;
try {
wavPtr = AquesTalk2_Synthe(koe, iSpeed, ref size, buffer); // throws
// phont ファイルを使用せず DLL 内蔵の音質だけ使う場合は
// 「phont ファイルを読み込む」部分の処理を削除し以下のように呼び出せば良い
//wavPtr = AquesTalk2_Synthe(koe, iSpeed, ref size, 0); // throws
// 失敗していれば終了する
if(wavPtr == IntPtr.Zero) {
Console.WriteLine("ERROR : 音声生成に失敗しました。不正な文字が使われた可能性があります。終了します");
return;
}
}
catch(Exception exception) {
Console.WriteLine("ERROR : 例外が発生しました");
Console.WriteLine(exception);
Console.WriteLine("終了します");
return;
}
// C# で扱えるようにマネージド側へコピーする
byte[] wav = new byte[size];
Marshal.Copy(wavPtr, wav, 0, size);
// アンマネージドポインタは用がなくなった瞬間に解放する
AquesTalk2_FreeWave(wavPtr);
// 同期再生する
using(var ms = new MemoryStream(wav))
using(var sp = new SoundPlayer(ms)) {
sp.PlaySync();
}
Console.WriteLine("Finished");
}
}
- 大枠は v1 系のモノと似ている。DLL インポート、関数呼び出し、
SoundPlayer.PlaySync()
で再生、という流れである AquesTalk2_Synthe
関数の引数の型などは v1 と異なっているので、詳細は公式の「プログラミングガイド」を参照のこと- ソース中にコメントで記したが、
.phont
ファイルを一切用意せず、DLL ファイルに内蔵のデフォルト音声だけでの利用もできる。必要なファイル数が減らせるので声質を変える必要がない場合に参考にしてほしい .phont
ファイルを読み込む部分のコードは自作。C# の作法などを知らないのでエラーハンドリングなど微妙かも。ツッコミがあれば教えてください
C# コードを csc.exe
でコンパイルする
前回の記事と同じく、.NET Framework の簡易的なコンパイラ、csc.exe
を使ってコンパイルする。前回と同様、32bit 指定でコンパイルしないと動作しない。
csc.exe
の所在やバージョンは環境によると思うが、自分の環境では以下のフルパスを指定してコンパイルした。
@Rem コンパイルする
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /nologo /platform:x86 .\atk2.cs
@Rem 実行する
.\atk2.exe
前回と同様、当然ながら DLL ファイルと .phont
ファイルは実行時に読み込むので、コンパイルした atk2.exe
と同じディレクトリに置いておくこと。
以上
v1 系と v2 系は声質データの扱い方が異なることがよく分かった。v1 系と同じ声質でも手直しが入っているのか、若干違って聴こえたりするので、好みのモノを選ぶと良いだろう。
v10 系も仕組みの違いはあるが、自前でプログラムを組むことは可能である。ただ、v10 系はプログラムの実行時にライセンスキーを指定してライセンス認証用の関数を実行することで評価版の制限を解除するような作りになっているらしく、v1・v2 系で示したような「SofTalk」同梱の DLL の流用では回避が難しそうである。
- AquesTalk10をUnity(WindowsおよびAndroid)から呼び出す - Qiita
- ishidafuu/AquesTalk10UnitySample
- AquesTalk10UnitySample/AquesTalk10SamplePlayer.cs at master · ishidafuu/AquesTalk10UnitySample
↑ 評価版で良ければ、上のコードが参考になると思われる。v10 系は様々なパラメータで読み上げ方を調整できるので、より高精度な読み上げを行わせたい場合は v10 系に手を出してみるのが良いだろう。
個人的には、世の「ゆっくり動画」で聞き馴染みがあるのは v1 系の声質なので、v1 系のライブラリで何か読み上げさせて自己満足しておこうかなーと思っている。