diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d4c99070a..e24d81036 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -346,3 +346,85 @@ jobs: # Add additional options to the MSBuild command line here (like platform or verbosity level). # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}} + + build-unix-cpp-example: + needs: [build-cpp-shared] + strategy: + fail-fast: false + matrix: + include: + - os: macos-latest + artifact_name: osx-universal2-cpu-cpp-shared + onnxruntime_url: https://github.com/microsoft/onnxruntime/releases/download/v1.10.0/onnxruntime-osx-universal2-1.10.0.tgz + onnxruntime_lib_name: libonnxruntime.1.10.0.dylib + core_name: libcore.dylib + + - os: ubuntu-latest + artifact_name: linux-x64-cpu-cpp-shared + onnxruntime_url: https://github.com/microsoft/onnxruntime/releases/download/v1.10.0/onnxruntime-linux-x64-1.10.0.tgz + onnxruntime_lib_name: libonnxruntime.so.1.10.0 + core_name: libcore.so + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - name: Download and extract artifact + uses: actions/download-artifact@v2 + id: download + with: + name: ${{ matrix.artifact_name }} + path: artifacts/ + + - name: Copy core library + shell: bash + run: | + cp ${{ steps.download.outputs.download-path }}/${{ matrix.core_name }} example/cpp/unix + + - run: mkdir download + + # ONNX Runtime + - name: Export ONNX Runtime url to calc hash + shell: bash + run: echo "${{ matrix.onnxruntime_url }}" > download/onnxruntime_url.txt + + - name: Cache ONNX Runtime + uses: actions/cache@v2 + id: onnxruntime-cache + with: + key: onnxruntime-cache-v1-${{ hashFiles('download/onnxruntime_url.txt') }} + path: download/onnxruntime + + # download/onnxruntime/lib/libonnxruntime.so + # download/onnxruntime/lib/libonnxruntime.dylib + - name: Download ONNX Runtime (tgz) + if: steps.onnxruntime-cache.outputs.cache-hit != 'true' + shell: bash + run: | + curl -L "${{ matrix.onnxruntime_url }}" > download/onnxruntime.tgz + mkdir -p download/onnxruntime + tar xf download/onnxruntime.tgz -C download/onnxruntime --strip-components 1 + rm download/onnxruntime.tgz + + - name: Copy ONNX Runtime + shell: bash + run: | + cp download/onnxruntime/lib/${{ matrix.onnxruntime_lib_name }} example/cpp/unix + + - if: startsWith(matrix.os, 'mac') + uses: jwlawson/actions-setup-cmake@v1.9 + + - name: Install build dependencies + if: startsWith(matrix.os, 'ubuntu') + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y cmake + + - name: Build + shell: bash + run: | + cd example/cpp/unix + cmake -S . -B build + cmake --build build diff --git a/example/cpp/unix/.gitignore b/example/cpp/unix/.gitignore new file mode 100644 index 000000000..c8cf6fb98 --- /dev/null +++ b/example/cpp/unix/.gitignore @@ -0,0 +1,9 @@ +# libraries +*.dylib +*.so + +# OpenJTalk-dictionary's dir +open_jtalk_dic_utf_8-* + +# executable +simple_tts diff --git a/example/cpp/unix/CMakeLists.txt b/example/cpp/unix/CMakeLists.txt new file mode 100644 index 000000000..df36d33d1 --- /dev/null +++ b/example/cpp/unix/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.16) + +project(SimpleTTS) + +add_executable(simple_tts simple_tts.cpp) + +find_library( + CORE_LIB + NAMES core libcore + HINTS "${CMAKE_SOURCE_DIR}" + NO_DEFAULT_PATH +) + +message(STATUS "CORE_LIB: ${CORE_LIB}") +if(NOT CORE_LIB) + message(FATAL_ERROR "Unable to find VOICEVOX core library") +endif() + +target_link_libraries(simple_tts ${CORE_LIB}) +set_property(TARGET simple_tts PROPERTY CXX_STANDARD 11) diff --git a/example/cpp/unix/README.md b/example/cpp/unix/README.md new file mode 100644 index 000000000..6211f2729 --- /dev/null +++ b/example/cpp/unix/README.md @@ -0,0 +1,64 @@ +# C++ サンプルコード(Linux・macOS 向け) + +voicevox_core ライブラリを C++ から使用するサンプルコード (`simple_tts.cpp`) です。ビルドするために C++ の開発環境(CMake 3.16 以上を含む)が必要です。 + + + +## 必要なファイルの準備 + +本ディレクトリに以下のファイル・フォルダを用意してください(あるいは、以下のファイル・フォルダへのシンボリックリンクでも良いです): + +- バージョン 0.12 以降の voicevox_core ライブラリ(配布ページ: https://github.com/VOICEVOX/voicevox_core/releases ) + - Linux の場合:`voicevox_core-linux-{お使いのCPUアーキテクチャ}-cpu-{バージョン}.zip` 内の `libcore.so` + - macOS の場合:`voicevox_core-osx-universal2-cpu-{バージョン}.zip` 内の `libcore.dylib` +- ONNX Runtime v1.10.0 の共有ライブラリ(配布ページ: https://github.com/microsoft/onnxruntime/releases/tag/v1.10.0 ) + - Linux の場合:`onnxruntime-linux-{お使いのCPUアーキテクチャ}-1.10.0.tgz` 内の `lib/libonnxruntime.so.1.10.0` + - macOS の場合:`onnxruntime-osx-universal2-1.10.0.tgz` 内の `lib/libonnxruntime.1.10.0.dylib` +- Open JTalk の辞書(配布ページ: http://open-jtalk.sourceforge.net/ ) + - 配布ページの "Dictionary for Open JTalk" 欄にある "Binary Package (UTF-8)" からダウンロードしてください + - 解凍してできた `open_jtalk_dic_utf_8-1.11` フォルダをそのままこのディレクトリに配置してください + +以上の準備を終えると、本ディレクトリには以下のファイル・フォルダが存在することになります: + +``` +CMakeLists.txt +libcore.so または libcore.dylib +libonnxruntime.so.1.10.0 または libonnxruntime.1.10.0.dylib +open_jtalk_dic_utf_8-1.11 +simple_tts.cpp +``` + + + +## ビルド + +以下のコマンドを実行すると、`build` ディレクトリが作成され、ビルド産物がその中に生成されます: + +```bash +cmake -S . -B build +cmake --build build +``` + + + +## 実行 + +`build` ディレクトリ以下にできた実行ファイル (`simple_tts`) をこのディレクトリにコピーしてから実行します: + +```bash +cp build/simple_tts . + +# ./simple_tts <読み上げさせたい文章> +./simple_tts これはテストです +``` + +正常に実行されれば `audio.wav` が生成されます。以下のコマンドですぐに聞くことができます: + +```bash +# Linux の場合 +aplay audio.wav + +# macOS の場合 +afplay audio.wav +``` + diff --git a/example/cpp/unix/simple_tts.cpp b/example/cpp/unix/simple_tts.cpp new file mode 100644 index 000000000..9c3a3b86e --- /dev/null +++ b/example/cpp/unix/simple_tts.cpp @@ -0,0 +1,56 @@ +#include +#include +#include + +#include "../../../core/src/core.h" + +#define OUTPUT_WAV_NAME "audio.wav" + +int main(int argc, char *argv[]) { + if (argc != 2) { + std::cout << "使い方: ./simple_tts <文章>" << std::endl; + return 0; + } + + std::string open_jtalk_dict_path("open_jtalk_dic_utf_8-1.11"); + std::string text(argv[1]); + + std::cout << "coreの初期化中..." << std::endl; + + if (!initialize(false)) { + std::cout << "coreの初期化に失敗しました" << std::endl; + return 1; + } + + VoicevoxResultCode result; + + std::cout << "openjtalk辞書の読み込み中..." << std::endl; + + result = voicevox_load_openjtalk_dict(open_jtalk_dict_path.c_str()); + if (result != VOICEVOX_RESULT_SUCCEED) { + std::cout << voicevox_error_result_to_message(result) << std::endl; + return 1; + } + + std::cout << "音声生成中..." << std::endl; + + int64_t speaker_id = 0; + int output_binary_size = 0; + uint8_t *output_wav = nullptr; + + result = voicevox_tts(text.c_str(), speaker_id, &output_binary_size, &output_wav); + if (result != VOICEVOX_RESULT_SUCCEED) { + std::cout << voicevox_error_result_to_message(result) << std::endl; + return 1; + } + + std::cout << "音声ファイル保存中..." << std::endl; + + std::ofstream wav_file(OUTPUT_WAV_NAME, std::ios::binary); + wav_file.write(reinterpret_cast(output_wav), output_binary_size); + voicevox_wav_free(output_wav); + + std::cout << "音声ファイル保存完了 (" << OUTPUT_WAV_NAME << ")" << std::endl; + + return 0; +}