Skip to content

Commit 58d64bc

Browse files
unlimitedsolasthibaul
authored andcommitted
libpiper migration
Migrate now deprecated/archived piper-phonemize[1] based cxxpiper implementation to libpiper[2] which was recently added to the upstream piper repository. Because we are now using the upstream libpiper C library directly, I figured we should probably also remove the cxx prefix from the module name. Changes made: - Removed conf options that new libpiper no longer support - Added peak normalization for parity with Python CLI - Simplified voice handling and configuration [1]: https://github.com/rhasspy/piper-phonemize [2]: https://github.com/OHF-Voice/piper1-gpl/tree/main/libpiper
1 parent 03183f1 commit 58d64bc

9 files changed

Lines changed: 618 additions & 1400 deletions

File tree

INSTALL

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,22 +152,26 @@ chmod +x autogen.sh
152152
make
153153
make install
154154

155-
Notes about cxxpiper support
156-
============================
155+
Notes about piper support
156+
=========================
157157

158-
The cxxpiper module uses the Piper synthesis
159-
https://github.com/rhasspy/piper/
158+
The piper module uses the Piper neural TTS engine
159+
https://github.com/OHF-Voice/piper1-gpl
160160

161-
Upstream piper however does not provide an API that can really be used nicely,
162-
so the build is quite convoluted. The following should be working:
161+
Speech Dispatcher links against the `libpiper` C shared library (and `librubberband`).
162+
To build and install `libpiper` from source:
163163

164-
wget https://github.com/rhasspy/piper-phonemize/releases/download/2023.11.14-4/piper-phonemize_linux_x86_64.tar.gz
165-
sudo tar -C /opt -xvf piper-phonemize_linux_x86_64.tar.gz
166-
wget https://github.com/rhasspy/piper/archive/refs/tags/2023.11.14-2.tar.gz
167-
sudo tar -C /opt -xvf 2023.11.14-2.tar.gz
168-
CXXFLAGS=-I/opt/piper_phonemize/include LDFLAGS=-L/opt/piper_phonemize/lib ./configure --with-piper=/opt/piper-2023.11.14-2
169-
make
170-
make install
164+
$ git clone https://github.com/OHF-Voice/piper1-gpl.git
165+
$ cd piper1-gpl/libpiper
166+
$ cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
167+
$ cmake --build build -j$(nproc)
168+
$ sudo cmake --install build
169+
170+
Then configure Speech Dispatcher with:
171+
$ ./configure --with-piper
172+
173+
(If libpiper is installed in a non-standard prefix like /opt/piper, use:
174+
$ ./configure --with-piper=/opt/piper)
171175

172176
Continue building Speech Dispatcher
173177
===================================

config/modules/Makefile.am

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ dist_moduleconforig_DATA += kali.conf
5454
endif
5555

5656
if piper_support
57-
dist_moduleconf_DATA += cxxpiper.conf
58-
dist_moduleconforig_DATA += cxxpiper.conf
57+
dist_moduleconf_DATA += piper.conf
58+
dist_moduleconforig_DATA += piper.conf
5959
endif
6060

6161
if ibmtts_support

config/modules/cxxpiper.conf

Lines changed: 0 additions & 75 deletions
This file was deleted.

config/modules/piper.conf

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#
2+
# Configuration for piper Speech Dispatcher output module.
3+
#
4+
5+
# Debugging level (0 = disabled, 1 = errors only, 5 = full debug)
6+
Debug 0
7+
8+
# -- Model Configuration --
9+
#
10+
# ModelPath is required. On Arch Linux (e.g. using the piper-voices-en-us package from AUR),
11+
# voices are installed to /usr/share/piper-voices/<lang>/<locale>/<voice>/<quality>/.
12+
#
13+
# en_US-lessac-medium is the recommended standard default voice.
14+
ModelPath "/usr/share/piper-voices/en/en_US/lessac/medium/en_US-lessac-medium.onnx"
15+
16+
# ConfigPath (optional):
17+
# Path to the voice's JSON configuration file. If omitted, piper automatically
18+
# looks for <ModelPath>.json.
19+
# ConfigPath "/usr/share/piper-voices/en/en_US/lessac/medium/en_US-lessac-medium.onnx.json"
20+
21+
# -- Multi-Speaker Voice Selection (Optional) --
22+
#
23+
# For single-speaker models (like lessac), a single voice named after the model stem is exposed.
24+
# For multi-speaker models (e.g., libritts_r, vctk, thorsten_emotional), each speaker defined in the
25+
# model's "speaker_id_map" is exposed as an individual voice.
26+
#
27+
# Listing available speaker names:
28+
# 1. Using the Speech Dispatcher CLI:
29+
# spd-say -o piper -L
30+
# 2. Inspecting the model's JSON configuration file directly:
31+
# jq '.speaker_id_map | keys' /path/to/model.onnx.json
32+
#
33+
# DefaultVoice (optional):
34+
# Sets the initial speaker for multi-speaker models using a speaker name from speaker_id_map.
35+
# DefaultVoice "8419"
36+
#
37+
# AddVoice (optional):
38+
# Maps standard Speech Dispatcher voice types (MALE1, FEMALE1, etc.) to specific speakers
39+
# within a language code.
40+
#
41+
# Examples for multi-speaker models:
42+
# AddVoice "en_US" "MALE1" "8419"
43+
# AddVoice "en_US" "FEMALE1" "4137"
44+
# AddVoice "de_DE" "MALE1" "neutral"
45+
# AddVoice "de_DE" "MALE2" "amused"
46+
47+
# -- Sound Icons --
48+
# Folder containing sound icon audio files (path must end with a trailing slash '/').
49+
SoundIconFolder "/usr/share/sounds/sound-icons/"
50+
51+
# -- ESpeak NG Data Directory --
52+
# Path to the espeak-ng-data directory used by Piper for phonemization.
53+
# On Arch Linux, this is installed by the 'espeak-ng' package to /usr/share/espeak-ng-data/.
54+
ESpeakNGDataDirPath "/usr/share/espeak-ng-data/"
55+
56+
# End of piper.conf

config/speechd.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ SymbolsPreprocFile "orca-math.dic"
287287
#AddModule "baratinoo" "sd_baratinoo" "baratinoo.conf"
288288
#AddModule "rhvoice" "sd_rhvoice" "rhvoice.conf"
289289
#AddModule "voxin" "sd_voxin" "voxin.conf"
290+
#AddModule "piper" "sd_piper" "piper.conf"
290291

291292
# The output module testing doesn't actually connect to anything. It
292293
# outputs the requested commands to standard output and reads

configure.ac

Lines changed: 44 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -427,70 +427,59 @@ AS_IF([test $with_kali != no], [output_modules="${output_modules} kali"])
427427

428428
# check for piper support
429429
AC_ARG_WITH([piper],
430-
[AS_HELP_STRING([--with-piper=/path], [include Piper support])],
430+
[AS_HELP_STRING([--with-piper[[=yes|no|check|/path]]], [include Piper TTS support])],
431431
[],
432-
[with_piper=no])
433-
AS_IF([test $with_espeak = yes -a $with_piper != no], [
434-
# We currently need various headers of piper
435-
PIPER_SRC_DIR="$with_piper/src/cpp"
432+
[with_piper=check])
433+
434+
AS_IF([test "$with_piper" != "no"], [
435+
PIPER_CFLAGS=""
436+
PIPER_LIBS=""
437+
AS_IF([test "$with_piper" != "yes" -a "$with_piper" != "check"], [
438+
PIPER_CFLAGS="-I$with_piper/include"
439+
PIPER_LIBS="-L$with_piper/lib -lpiper"
440+
])
436441
OLDCXXFLAGS="$CXXFLAGS"
437442
OLDLDFLAGS="$LDFLAGS"
438-
CXXFLAGS="$CXXFLAGS -I$PIPER_SRC_DIR"
439-
440-
AS_IF([test $with_piper != no],
441-
[PKG_CHECK_MODULES([ONNXRUNTIME], [libonnxruntime], [
442-
CXXFLAGS="$CXXFLAGS $ONNXRUNTIME_CFLAGS"
443-
LDFLAGS="$LDFLAGS $ONNXRUNTIME_LIBS"
444-
], [AC_CHECK_LIB([onnxruntime], [OrtGetApiBase],
445-
[ONNXRUNTIME_LIBS="-lonnxruntime"],
446-
[with_piper=no])
447-
])])
448-
449-
AS_IF([test $with_piper != no],
450-
[PKG_CHECK_MODULES([RUBBERBAND], [rubberband], [
451-
CXXFLAGS="$CXXFLAGS $RUBBERBAND_CFLAGS"
452-
LDFLAGS="$LDFLAGS $RUBBERBAND_LIBS"
453-
], [with_piper=no])])
443+
OLDLIBS="$LIBS"
444+
CXXFLAGS="$CXXFLAGS $PIPER_CFLAGS"
445+
LDFLAGS="$LDFLAGS $PIPER_LIBS"
454446
455447
AC_LANG_PUSH(C++)
456-
AS_IF([test $with_piper != no],
457-
[AC_CHECK_LIB([piper_phonemize], [_ZN5piper19DEFAULT_PHONEME_MAPB5cxx11E],
458-
[:],
459-
[with_piper=no])])
460-
461-
AS_IF([test $with_piper != no],
462-
[AC_CHECK_HEADER([json.hpp],
463-
[],
464-
[with_piper=no])])
465-
AS_IF([test $with_piper != no],
466-
[AC_CHECK_HEADER([piper.hpp],
467-
[],
468-
[with_piper=no])])
469-
AS_IF([test $with_piper != no],
470-
[AC_CHECK_HEADER([utf8.h],
471-
[],
472-
[with_piper=no])])
473-
AS_IF([test $with_piper != no],
474-
[AC_CHECK_HEADER([wavfile.hpp],
475-
[],
476-
[with_piper=no])])
477-
478-
AS_IF([test $with_piper != no],
479-
# We need espeak with https://github.com/espeak-ng/espeak-ng/pull/2127 applied
480-
[AC_CHECK_LIB([espeak-ng], [espeak_TextToPhonemesWithTerminator],
481-
[:],
482-
[with_piper=no],
483-
[$ESPEAK_NG_LIBS])])
484-
448+
# Check for piper.h header
449+
AC_CHECK_HEADER([piper.h], [have_piper_h=yes], [have_piper_h=no])
450+
# Check for libpiper library
451+
AC_CHECK_LIB([piper], [piper_create], [have_libpiper=yes], [have_libpiper=no])
452+
# Check for nlohmann json
453+
AC_CHECK_HEADER([nlohmann/json.hpp], [have_json_h=yes], [
454+
AC_CHECK_HEADER([json.hpp], [have_json_h=yes], [have_json_h=no])
455+
])
485456
AC_LANG_POP(C++)
457+
486458
CXXFLAGS="$OLDCXXFLAGS"
487459
LDFLAGS="$OLDLDFLAGS"
460+
LIBS="$OLDLIBS"
461+
462+
AS_IF([test "$have_piper_h" = "yes" -a "$have_libpiper" = "yes" -a "$have_json_h" = "yes"], [
463+
PKG_CHECK_MODULES([RUBBERBAND], [rubberband], [
464+
AS_IF([test -z "$PIPER_LIBS"], [PIPER_LIBS="-lpiper"])
465+
with_piper=yes
466+
], [
467+
AS_IF([test "$with_piper" = "yes"], [
468+
AC_MSG_FAILURE([rubberband is required for piper])
469+
])
470+
with_piper=no
471+
])
472+
], [
473+
AS_IF([test "$with_piper" = "yes"], [
474+
AC_MSG_FAILURE([libpiper (piper.h, libpiper, and json.hpp) is not available])
475+
])
476+
with_piper=no
477+
])
488478
])
489-
AM_CONDITIONAL([piper_support], [test $with_piper != no])
490-
AS_IF([test $with_piper != no], [output_modules="${output_modules} cxxpiper"])
491-
AC_SUBST([PIPER_SRC_DIR])
492-
AC_SUBST([ONNXRUNTIME_CFLAGS])
493-
AC_SUBST([ONNXRUNTIME_LIBS])
479+
AM_CONDITIONAL([piper_support], [test "$with_piper" = "yes"])
480+
AS_IF([test "$with_piper" = "yes"], [output_modules="${output_modules} piper"])
481+
AC_SUBST([PIPER_CFLAGS])
482+
AC_SUBST([PIPER_LIBS])
494483
AC_SUBST([RUBBERBAND_CFLAGS])
495484
AC_SUBST([RUBBERBAND_LIBS])
496485

src/modules/Makefile.am

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -295,16 +295,14 @@ endif
295295
endif
296296

297297
#
298-
# cxxpiper
298+
# piper
299299
#
300300
if piper_support
301-
modulebin_PROGRAMS += sd_cxxpiper
302-
sd_cxxpiper_SOURCES = cxxpiper.cpp module_utils_addvoice.c module_utils_play.c $(common_SOURCES)
303-
sd_cxxpiper_CPPFLAGS = -I$(PIPER_SRC_DIR) $(ONNXRUNTIME_CFLAGS) $(RUBBERBAND_CFLAGS) $(AM_CPPFLAGS)
304-
sd_cxxpiper_LDADD = $(top_builddir)/src/common/libcommon.la \
305-
-lpiper_phonemize \
306-
$(ONNXRUNTIME_LIBS) \
307-
-lespeak-ng \
301+
modulebin_PROGRAMS += sd_piper
302+
sd_piper_SOURCES = piper.cpp module_utils_addvoice.c module_utils_play.c $(common_SOURCES)
303+
sd_piper_CPPFLAGS = $(PIPER_CFLAGS) $(RUBBERBAND_CFLAGS) $(AM_CPPFLAGS)
304+
sd_piper_LDADD = $(top_builddir)/src/common/libcommon.la \
305+
$(PIPER_LIBS) \
308306
$(RUBBERBAND_LIBS) \
309307
$(SNDFILE_LIBS) \
310308
$(common_LDADD)

0 commit comments

Comments
 (0)