SHAREVOX core の API を探る(1)CMake

Explore the SHAREVOX core API (1) CMake


2022/12/19
藤田昭人


ここ数年は、 この時期になると ゲスト・スピーカーの準備に 追われるのが常で、 特に去年は例の音声チャットボットの プロトタイプ作成に追い立てられる 日々を過ごしてました。 今年は夏の3ヶ月完全休業を 取り返していたこともあって 「去年と同じメニューで授業」 と秋口あたりから相談してました。なので 「今年は平穏な年末を過ごせそうだ」 と鷹を括っていたのですが…

やはり今年も悪夢からは逃れられなかった😀

実は、昨年の実習教材が突如動かなくなったのでした*1。 その対応に追われて授業準備の予定は総崩れ。 おかげでブログの続きを公開するのが だいぶん遅れてしまいました。

さて…

今回から数回、 SHAREVOX core を使ったプログラミングを紹介していきます。 実は授業で 「ちょっとしたデモぐらい見せたい」 とコードと ブログの下書きを 書き溜めていたのです。 が、結構な分量になってしまったので トピックごと小出しして行くことにしました。


SHAREVOX core の API

まずはSHAREVOX core の API をざっくり概観していきます。 SHAREVOX core のREADME.mdによれば、 「APIは core/src/core.h を見ろ」と書いてますが、中身は doxygenフォーマットの インターフェース情報でした。 関数名だけ抜き書きすると…

関数名 説明
1 initialize 初期化する
2 load_model モデルをロードする
3 is_model_loaded モデルがロード済みかどうか
4 finalize 終了処理を行う
5 metas メタ情報を取得する
6 supported_devices 対応デバイス情報を取得する
7 variance_forward 音素ごとの音高と長さを求める
8 decode_forward 波形を求める
9 last_error_message 最後に発生したエラーのメッセージを取得する
10 sharevox_load_openjtalk_dict open jtalkの辞書を読み込む
11 sharevox_tts text to spearchを実行する
12 sharevox_tts_from_kana text to spearchをAquesTalkライクな記法で実行する
13 sharevox_wav_free voicevox_ttsで生成した音声データを開放する
14 sharevox_error_result_to_message エラーで返ってきた結果コードをメッセージに変換する

…と、音声合成に関わりがありそうな 14エントリーが定義されていました。

付属するサンプルソースexample/cpp/unix/simple_tts.cpp を眺めると、このうち initialize, sharevox_load_openjtalk_dict, sharevox_tts, sharevox_wav_free, finalize を呼び出しているようです。 このプログラムは比較的フラットで SHAREVOX core の API を探るための もっとも単純なサンプルとして 活用できそうです。


SimpleTTS のディレクトリを作り直す

早速 simple_tts.cpp を手直しして ライブラリーの挙動を確認することにしたのですが…

このプログラムは見ての通り ディレクトリ・ネストの深いところにあり( 前回 の手順を実行した方はご存知のとおり) ビルドするためには関連ライブラリーを ローカルディレクトリに コピーしてくる必要があります。


CMakeLists.txt を書いてみる

そこでトップディレクトリ直下に 新たなディレクトリを作り、 関連ライブラリーを移動することなく ビルドできるように CMakeLists.txt を作成します。

初心者向けのサンプルを探して いろいろチェックしてみたのですが、 Wikipedia 英語版のCMakeのページにある Example に掲載されている次のコードが 一番シンプルでわかりやすい例のようです。

// hello.cpp
#include <iostream>

int main()
{
    std::cout << "Hello, world!\n";
}

という C++ のコードをビルドするための CMakeLists.txt は次のようになります。

cmake_minimum_required(VERSION 3.5)
project(HelloWorld CXX)
add_executable(hello hello.cpp)

この記法、年寄りの僕には かつて書いていた BSD UnixMakefile を彷彿させます。 等価な Makefile を書くと、 確かこんな感じ…

PROG= hello
SRCS=  hello.c

ということで CMake によるビルド手順の記述方法を 感覚的に理解したところで simple_tts.cpp のために僕が用意したのは以下の CMakeLists.txt です。

cmake_minimum_required(VERSION 3.16)
project(SimpleTTS)
set(CMAKE_CXX_STANDARD 11)

find_path(PARENT NAMES "sharevox_core-0.1.2" PATHS "../..")
message(STATUS "PARENT: ${PARENT}")
set(TOP_DIR "${PARENT}/sharevox_core-0.1.2")
message(STATUS "TOP_DIR: ${TOP_DIR}")
find_library(CORE_LIB NAMES core PATHS "${TOP_DIR}/core" PATH_SUFFIXES lib)
message(STATUS "CORE_LIB: ${CORE_LIB}")

add_executable(simple_tts simple_tts.cpp)
target_link_libraries(simple_tts ${CORE_LIB})

要は SHAREVOX core のライブラリの格納位置は トップディレクトリから相対パスが決まっているとの 仮定の元に find_path なるコマンドで トップディレクトリを探しに行っています。あと message(STATUS, "XXX") なる記法は、かつての echo "XXX" と等価と考えれば良いみたい。


新しいディレクトリで simple_tts をビルドしてみる

CMakeLists.txt が用意できたら simple_tts をビルドしてみましょう。

【注】ターミナルソフトで UNIX コマンドを使ってください。

  • まずは 前回 紹介した手順で SHAREVOX core のビルドツリーを用意し、 ビルドしてください。
$ ls sharevox_core-0.1.2/core/lib
core.h              libonnxruntime.dylib
libcore.dylib           libopenjtalk.a
libonnxruntime.1.10.0.dylib
$ 

上記のように core/lib にライブラリのバイナリが確認できればOKです。

$ cd sharevox_core-0.1.2
$ mkdir simple_tts
$ cd simple_tts
$ vi CMakeLists.txt
<中略>
$ cp ../example/cpp/unix/simple_tts.cpp .
$ vi simple_tts.cpp
<中略>
$ diff -u ../example/cpp/unix/simple_tts.cpp simple_tts.cpp
--- ../example/cpp/unix/simple_tts.cpp  2022-10-28 17:21:34.000000000 +0900
+++ simple_tts.cpp  2022-12-20 13:35:13.000000000 +0900
@@ -2,7 +2,7 @@
 #include <iostream>
 #include <string>

-#include "../../../core/src/core.h"
+#include "../core/src/core.h"

 #define OUTPUT_WAV_NAME "audio.wav"

@@ -17,7 +17,7 @@

   std::cout << "coreの初期化中..." << std::endl;

-  if (!initialize("../../../model", false)) {
+  if (!initialize("../model", false)) {
     std::cout << "coreの初期化に失敗しました" << std::endl;
     return 1;
   }
$ 

トップディレクトリで simple_tts を作成し、 前述の CMakeLists.txt と simple_tts.cpp を置きます。 simple_tts.cpp はオリジナルをコピーしてきますが、 上記の通り、インクルードするヘッダーファイルのパスを変更してください。

$ mkdir build
$ cd build
$ cmake ..
-- The C compiler identification is AppleClang 13.0.0.13000029
-- The CXX compiler identification is AppleClang 13.0.0.13000029
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- PARENT: /Users/fujita/xtr/BookBot/BookBot3/03_T2S_CMake
-- TOP_DIR: /Users/fujita/xtr/BookBot/BookBot3/03_T2S_CMake/sharevox_core-0.1.2
-- CORE_LIB: /Users/fujita/xtr/BookBot/BookBot3/03_T2S_CMake/sharevox_core-0.1.2/core/lib/libcore.dylib
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/fujita/xtr/BookBot/BookBot3/03_T2S_CMake/sharevox_core-0.1.2/simple_tts/build
$ cmake --build .
[ 50%] Building CXX object CMakeFiles/simple_tts.dir/simple_tts.cpp.o
[100%] Linking CXX executable simple_tts
[100%] Built target simple_tts
$ ls
CMakeCache.txt      Makefile        simple_tts
CMakeFiles      cmake_install.cmake
$ 

これも 前回 と同じ手順になります。


ずいぶん丁寧な CMakeLists.txt の解説になっちゃいましたが…

元々 cmake コマンドは X Window の imake や GNU の autoconf など UNIX の make コマンドの Makefile を自動生成するコマンドだったはずで、 今では大幅に機能強化されていて「覚えるのが大変」なコマンドですが、 オリジナルの記法に立ち戻れば案外スラッと書けるなぁ…感慨しているところです😀

ちなみに、件の授業は 12/15 に終わってまして、 相方の吉田さんに「今回のブログは連続5日間連続投稿」と 啖呵を切ってしまったので、一発目はこのへんで…
明日もがんばります。

それではお約束の…

#つくよみちゃんを利用してフォロワー増やしたい

以上

*1:蓋を開ければ大したことではなかったのですが、 やはり最初にみつけた時は衝撃的だったのは確か😀