Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shared lib build support #276

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ endif()

add_executable(piper src/cpp/main.cpp src/cpp/piper.cpp)
add_executable(test_piper src/cpp/test.cpp src/cpp/piper.cpp)
add_library(piperlib SHARED src/cpp/piperlib.cpp src/cpp/piper.cpp)

# NOTE: external project prefix are shortened because of path length restrictions on Windows
# NOTE: onnxruntime is pulled from piper-phonemize
Expand All @@ -39,6 +40,7 @@ if(NOT DEFINED FMT_DIR)
)
add_dependencies(piper fmt_external)
add_dependencies(test_piper fmt_external)
add_dependencies(piperlib fmt_external)
endif()

# ---- spdlog ---
Expand All @@ -50,10 +52,11 @@ if(NOT DEFINED SPDLOG_DIR)
spdlog_external
PREFIX "${CMAKE_CURRENT_BINARY_DIR}/s"
URL "https://github.com/gabime/spdlog/archive/refs/tags/v${SPDLOG_VERSION}.zip"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SPDLOG_DIR}
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SPDLOG_DIR} -DCMAKE_BUILD_TYPE=Release
)
add_dependencies(piper spdlog_external)
add_dependencies(test_piper spdlog_external)
add_dependencies(piperlib spdlog_external)
endif()

# ---- piper-phonemize ---
Expand All @@ -68,6 +71,7 @@ if(NOT DEFINED PIPER_PHONEMIZE_DIR)
)
add_dependencies(piper piper_phonemize_external)
add_dependencies(test_piper piper_phonemize_external)
add_dependencies(piperlib piper_phonemize_external)
endif()

# ---- Declare executable ----
Expand Down Expand Up @@ -104,6 +108,39 @@ target_include_directories(piper PUBLIC

target_compile_definitions(piper PUBLIC _PIPER_VERSION=${piper_version})


# ---- Declare library ----

if((NOT MSVC) AND (NOT APPLE))
# Linux flags
string(APPEND CMAKE_CXX_FLAGS " -Wall -Wextra -Wl,-rpath,'$ORIGIN'")
string(APPEND CMAKE_C_FLAGS " -Wall -Wextra")
target_link_libraries(piperlib -static-libgcc -static-libstdc++)

set(PIPER_EXTRA_LIBRARIES "pthread")
endif()

target_link_libraries(piperlib
fmt
spdlog
espeak-ng
piper_phonemize
onnxruntime
${PIPER_EXTRA_LIBRARIES}
)

target_link_directories(piperlib PUBLIC
${FMT_DIR}/lib
${SPDLOG_DIR}/lib
${PIPER_PHONEMIZE_DIR}/lib
)

target_include_directories(piperlib PUBLIC
${FMT_DIR}/include
${SPDLOG_DIR}/include
${PIPER_PHONEMIZE_DIR}/include
)

# ---- Declare test ----
include(CTest)
enable_testing()
Expand Down Expand Up @@ -170,3 +207,8 @@ install(
FILES ${PIPER_PHONEMIZE_DIR}/share/libtashkeel_model.ort
DESTINATION ${CMAKE_INSTALL_PREFIX}
)

install(
TARGETS piperlib
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}
)
122 changes: 122 additions & 0 deletions src/cpp/piperlib.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#include "piper.hpp"
#include "piperlib.hpp"
#include <cstring>

extern "C"
{
eSpeakConfig* create_eSpeakConfig() {
return new eSpeakConfig();
}

void destroy_eSpeakConfig(eSpeakConfig* config) {
delete config;
}

PiperConfig* create_PiperConfig(char* eSpeakDataPath) {
auto config = new PiperConfig();
config->eSpeakDataPath = eSpeakDataPath;
return config;
}

void destroy_PiperConfig(PiperConfig* config) {
delete config;
}

PhonemizeConfig* create_PhonemizeConfig() {
return new PhonemizeConfig();
}

void destroy_PhonemizeConfig(PhonemizeConfig* config) {
delete config;
}

SynthesisConfig* create_SynthesisConfig() {
return new SynthesisConfig();
}

void destroy_SynthesisConfig(SynthesisConfig* config) {
delete config;
}

ModelConfig* create_ModelConfig() {
return new ModelConfig();
}

void destroy_ModelConfig(ModelConfig* config) {
delete config;
}

ModelSession* create_ModelSession() {
return new ModelSession();
}

void destroy_ModelSession(ModelSession* config) {
delete config;
}

SynthesisResult* create_SynthesisResult() {
return new SynthesisResult();
}

void destroy_SynthesisResult(SynthesisResult* config) {
delete config;
}

Voice* create_Voice() {
return new Voice();
}

void destroy_Voice(Voice* voice) {
delete voice;
}

bool isSingleCodepoint(const char* s) {
std::string str(s);
return piper::isSingleCodepoint(str);
}

char32_t getCodepoint(const char* s) {
return piper::getCodepoint(s);
}

char* getVersion() {
auto version = piper::getVersion();
char* cstr = new char[version.size() + 1];
std::strcpy(cstr, version.c_str());
return cstr;
}

void initializePiper(PiperConfig* config) {
piper::initialize(*config);
}

void terminatePiper(PiperConfig* config) {
piper::terminate(*config);
}

SynthesisConfig getSynthesisConfig(Voice* voice) {
return voice->synthesisConfig;
}

void loadVoice(PiperConfig* config, const char* modelPath, const char* modelConfigPath, Voice* voice, int64_t* speakerId) {
std::optional<piper::SpeakerId> optSpeakerId;
if (speakerId) {
optSpeakerId = *speakerId;
}
piper::loadVoice(*config, modelPath, modelConfigPath, *voice, optSpeakerId);
}

void textToAudio(PiperConfig* config, Voice* voice, const char* text, SynthesisResult* result, AudioCallback audioCallback) {
std::vector<int16_t> audioBuf;
piper::textToAudio(*config, *voice, text, audioBuf, *result, [&audioBuf, audioCallback] { audioCallback(audioBuf.data(), audioBuf.size()); });
}

void textToWavFile(PiperConfig* config, Voice* voice, const char* text, const char* audioFile, SynthesisResult* result) {
std::string audioFilePath = audioFile;
std::ofstream audioFileStream(audioFilePath, std::ios::binary);
piper::textToWavFile(*config, *voice, text, audioFileStream, *result);
audioFileStream << "opened";
audioFileStream.flush();
audioFileStream.close();
}
}
42 changes: 42 additions & 0 deletions src/cpp/piperlib.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <stdint.h>
#include <stdbool.h>
#include "piper.hpp"

using namespace piper;

#if defined(_WIN32) && !defined(__MINGW32__)
# define PIPER_API __declspec(dllexport)
#else
# define PIPER_API __attribute__ ((visibility ("default")))
#endif

extern "C" {
typedef void (*AudioCallback)(int16_t* audioBuffer, int length);

PIPER_API eSpeakConfig* create_eSpeakConfig();
PIPER_API void destroy_eSpeakConfig(eSpeakConfig* config);
PIPER_API PiperConfig* create_PiperConfig(char* eSpeakDataPath);
PIPER_API void destroy_PiperConfig(PiperConfig* config);
PIPER_API PhonemizeConfig* create_PhonemizeConfig();
PIPER_API void destroy_PhonemizeConfig(PhonemizeConfig* config);
PIPER_API SynthesisConfig* create_SynthesisConfig();
PIPER_API void destroy_SynthesisConfig(SynthesisConfig* config);
PIPER_API ModelConfig* create_ModelConfig();
PIPER_API void destroy_ModelConfig(ModelConfig* config);
PIPER_API ModelSession* create_ModelSession();
PIPER_API void destroy_ModelSession(ModelSession* config);
PIPER_API SynthesisResult* create_SynthesisResult();
PIPER_API void destroy_SynthesisResult(SynthesisResult* config);
PIPER_API Voice* create_Voice();
PIPER_API void destroy_Voice(Voice* voice);

PIPER_API bool isSingleCodepoint(const char* s);
PIPER_API char32_t getCodepoint(const char* s);
PIPER_API char* getVersion();
PIPER_API void initializePiper(PiperConfig* config);
PIPER_API void terminatePiper(PiperConfig* config);
PIPER_API SynthesisConfig getSynthesisConfig(Voice* voice);
PIPER_API void loadVoice(PiperConfig* config, const char* modelPath, const char* modelConfigPath, Voice* voice, SpeakerId* speakerId);
PIPER_API void textToAudio(PiperConfig* config, Voice* voice, const char* text, SynthesisResult* result, AudioCallback audioCallback);
PIPER_API void textToWavFile(PiperConfig* config, Voice* voice, const char* text, const char* audioFile, SynthesisResult* result);
}