1
1
#include " phonemizer.h"
2
2
3
- /*
3
+ #ifdef ESPEAK_INSTALL
4
+ /* *
5
+ * espeak_wrapper functions and assignments
6
+ *
7
+ * The espeak_wrapper is a singleton which wraps threaded calls to espeak-ng with a shared mutex
8
+ */
9
+
10
+ // non-const static members must be initialized out of line
11
+ espeak_wrapper* espeak_wrapper::instance{nullptr };
12
+ std::mutex espeak_wrapper::mutex;
13
+
14
+ espeak_wrapper * espeak_wrapper::get_instance () {
15
+ if (!instance) {
16
+ instance = new espeak_wrapper;
17
+ }
18
+ return instance;
19
+ }
20
+
21
+ const espeak_VOICE ** espeak_wrapper::list_voices () {
22
+ std::lock_guard<std::mutex> lock (mutex);
23
+ return espeak_ListVoices (nullptr );
24
+ }
25
+
26
+ espeak_ERROR espeak_wrapper::set_voice (const char * voice_code) {
27
+ std::lock_guard<std::mutex> lock (mutex);
28
+ return espeak_SetVoiceByName (voice_code);
29
+ }
30
+
31
+ const char * espeak_wrapper::text_to_phonemes (const void ** textptr, int textmode, int phonememode) {
32
+ std::lock_guard<std::mutex> lock (mutex);
33
+ return espeak_TextToPhonemes (textptr, textmode, phonememode);
34
+ }
35
+
36
+ void espeak_wrapper::initialize (espeak_AUDIO_OUTPUT output, int buflength, const char * path, int options) {
37
+ std::lock_guard<std::mutex> lock (mutex);
38
+ if (!espeak_initialized) {
39
+ espeak_initialized = true ;
40
+ espeak_Initialize (output, buflength, path, options);
41
+ }
42
+ }
43
+ #endif
44
+
45
+ /* *
4
46
* Helper functions for string parsing
5
47
*/
6
48
const std::unordered_set<std::string> inline_combine_sets (const std::vector<std::unordered_set<std::string>> sets) {
@@ -131,7 +173,7 @@ std::string parse_voice_code(std::string voice_code) {
131
173
if (search_by_id || search_by_lcc) {
132
174
voice_code = replace (voice_code, ' _' , ' -' );
133
175
}
134
- const espeak_VOICE** espeak_voices = espeak_ListVoices ( nullptr );
176
+ const espeak_VOICE** espeak_voices = espeak_wrapper::get_instance ()-> list_voices ( );
135
177
// ideally we'd use the espeak voice scores which order voices by preference, but they are only returned when a voice_spec is passed to the list api and
136
178
// the voice spec isn't compatible with partials (e.g. country codes, language family code, etc)
137
179
int i = 0 ;
@@ -194,10 +236,10 @@ std::string parse_voice_code(std::string voice_code) {
194
236
195
237
void update_voice (std::string voice_code) {
196
238
#ifdef ESPEAK_INSTALL
197
- espeak_ERROR e = espeak_SetVoiceByName (voice_code.c_str ());
239
+ espeak_ERROR e = espeak_wrapper::get_instance ()-> set_voice (voice_code.c_str ());
198
240
if (e != EE_OK) {
199
241
voice_code = parse_voice_code (voice_code);
200
- espeak_SetVoiceByName (voice_code.c_str ());
242
+ espeak_wrapper::get_instance ()-> set_voice (voice_code.c_str ());
201
243
}
202
244
#else
203
245
TTS_ABORT (" Attempted to set voice without espeak-ng installed." );
@@ -951,7 +993,7 @@ bool phonemizer::route(corpus * text, std::string* output, conditions * flags) {
951
993
std::string phonemizer::espeak_text_to_phonemes (const char * text) {
952
994
int mode = phoneme_mode == IPA ? (0 << 8 | 0x02 ) : (0 << 8 | 0x01 );
953
995
const void ** txt_ptr = (const void **)&text;
954
- const char * resp = espeak_TextToPhonemes (txt_ptr, espeakCHARS_UTF8, mode);
996
+ const char * resp = espeak_wrapper::get_instance ()-> text_to_phonemes (txt_ptr, espeakCHARS_UTF8, mode);
955
997
return strip (std::string (resp));
956
998
}
957
999
#endif
@@ -1083,7 +1125,7 @@ struct phonemizer * phonemizer_from_gguf(gguf_context * meta, const std::string
1083
1125
1084
1126
if ((phonemizer_type) ph_type == ESPEAK) {
1085
1127
#ifdef ESPEAK_INSTALL
1086
- espeak_Initialize (AUDIO_OUTPUT_SYNCHRONOUS, 0 , ESPEAK_DATA_PATH, 0 );
1128
+ espeak_wrapper::get_instance ()-> initialize (AUDIO_OUTPUT_SYNCHRONOUS, 0 , ESPEAK_DATA_PATH, 0 );
1087
1129
1088
1130
update_voice (espeak_voice_code);
1089
1131
@@ -1109,7 +1151,7 @@ struct phonemizer * phonemizer_from_gguf(gguf_context * meta, const std::string
1109
1151
1110
1152
struct phonemizer * espeak_phonemizer (bool use_espeak_phonemes, std::string espeak_voice_code) {
1111
1153
#ifdef ESPEAK_INSTALL
1112
- espeak_Initialize (AUDIO_OUTPUT_SYNCHRONOUS, 0 , ESPEAK_DATA_PATH, 0 );
1154
+ espeak_wrapper::get_instance ()-> initialize (AUDIO_OUTPUT_SYNCHRONOUS, 0 , ESPEAK_DATA_PATH, 0 );
1113
1155
1114
1156
update_voice (espeak_voice_code);
1115
1157
0 commit comments