From c46e58d479cd3719b424e635052c27566ddc04cc Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 23 Jul 2025 17:27:47 +0530 Subject: [PATCH] Start work on getting rid of piper code and only using the model data The inference code if a few hundred lines anyway, piper is unmaintained and forked and the fork depends on the gigantic python ONNXRuntime bindings. Just write the few hundred lines myself. --- setup/build_environment.py | 6 +++++ setup/extensions.json | 8 +++++++ src/calibre/constants.py | 1 + src/calibre/utils/tts/__init__.py | 0 src/calibre/utils/tts/piper.cpp | 39 +++++++++++++++++++++++++++++++ src/calibre/utils/tts/piper.py | 6 +++++ 6 files changed, 60 insertions(+) create mode 100644 src/calibre/utils/tts/__init__.py create mode 100644 src/calibre/utils/tts/piper.cpp create mode 100644 src/calibre/utils/tts/piper.py diff --git a/setup/build_environment.py b/setup/build_environment.py index 754ab4ce03..4adda7f415 100644 --- a/setup/build_environment.py +++ b/setup/build_environment.py @@ -153,6 +153,8 @@ uchardet_inc_dirs, uchardet_lib_dirs, uchardet_libs = [], [], ['uchardet'] openssl_inc_dirs, openssl_lib_dirs = [], [] +piper_inc_dirs, piper_lib_dirs, piper_libs = [], [], [] + ICU = sw = '' if iswindows: @@ -211,6 +213,10 @@ else: uchardet_inc_dirs = pkgconfig_include_dirs('uchardet', '', '/usr/include/uchardet') uchardet_lib_dirs = pkgconfig_lib_dirs('uchardet', '', '/usr/lib') uchardet_libs = pkgconfig_libs('uchardet', '', '') + piper_inc_dirs = pkgconfig_include_dirs('espeak-ng', '', '/usr/include') + pkgconfig_include_dirs( + 'libonnxruntime', '', '/usr/include/onnxruntime') + piper_lib_dirs = pkgconfig_lib_dirs('espeak-ng', '', '/usr/lib') + pkgconfig_lib_dirs('libonnxruntime', '', '/usr/lib') + piper_libs = pkgconfig_libs('espeak-ng', '', 'espeak-ng') + pkgconfig_libs('libonnxruntime', '', 'onnxruntime') for x in ('libavcodec', 'libavformat', 'libavdevice', 'libavfilter', 'libavutil', 'libpostproc', 'libswresample', 'libswscale'): for inc in pkgconfig_include_dirs(x, '', '/usr/include'): if inc and inc not in ffmpeg_inc_dirs: diff --git a/setup/extensions.json b/setup/extensions.json index c105031409..b39ce6d996 100644 --- a/setup/extensions.json +++ b/setup/extensions.json @@ -134,6 +134,14 @@ "error": "!podofo_error", "needs_c++": "17" }, + { + "name": "piper", + "sources": "calibre/utils/tts/piper.cpp", + "needs_c++": "17", + "libraries": "!piper_libs", + "lib_dirs": "!piper_lib_dirs", + "inc_dirs": "!piper_inc_dirs" + }, { "name": "html_as_json", "sources": "calibre/srv/html_as_json.cpp", diff --git a/src/calibre/constants.py b/src/calibre/constants.py index 7c5fd39ef0..7ac71da553 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -258,6 +258,7 @@ class ExtensionsImporter: 'rcc_backend', 'icu', 'speedup', + 'piper', 'html_as_json', 'fast_css_transform', 'fast_html_entities', diff --git a/src/calibre/utils/tts/__init__.py b/src/calibre/utils/tts/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/calibre/utils/tts/piper.cpp b/src/calibre/utils/tts/piper.cpp new file mode 100644 index 0000000000..5ab9771c0a --- /dev/null +++ b/src/calibre/utils/tts/piper.cpp @@ -0,0 +1,39 @@ +/* + * piper.cpp + * Copyright (C) 2025 Kovid Goyal + * + * Distributed under terms of the GPL3 license. + */ +#define PY_SSIZE_T_CLEAN + +#include +#include + +static PyObject* +phonemize(PyObject *self, PyObject *args) { + Py_RETURN_NONE; +} + +// Boilerplate {{{ +static char doc[] = "Text to speech using the Piper TTS models"; +static PyMethodDef methods[] = { + {"phonemize", (PyCFunction)phonemize, METH_VARARGS, + "Convert the specified text into espeak-ng phonemes" + }, + {NULL} /* Sentinel */ +}; +static int +exec_module(PyObject *mod) { return 0; } + +static PyModuleDef_Slot slots[] = { {Py_mod_exec, (void*)exec_module}, {0, NULL} }; + +static struct PyModuleDef module_def = {PyModuleDef_HEAD_INIT}; + +CALIBRE_MODINIT_FUNC PyInit_piper(void) { + module_def.m_name = "piper"; + module_def.m_slots = slots; + module_def.m_doc = doc; + module_def.m_methods = methods; + return PyModuleDef_Init(&module_def); +} +// }}} diff --git a/src/calibre/utils/tts/piper.py b/src/calibre/utils/tts/piper.py new file mode 100644 index 0000000000..88610e3f37 --- /dev/null +++ b/src/calibre/utils/tts/piper.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python +# License: GPLv3 Copyright: 2025, Kovid Goyal + +import calibre_extensions.piper as piper + +piper