Skip to content

Commit 0fc289e

Browse files
committed
Propagate changes to libpiper
1 parent 68930fc commit 0fc289e

5 files changed

Lines changed: 62 additions & 44 deletions

File tree

libpiper/include/piper_impl.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ Ort::Env ort_env{ORT_LOGGING_LEVEL_WARNING, "piper"};
4545

4646
#define CLAUSE_TYPE_CLAUSE 0x00040000
4747
#define CLAUSE_TYPE_SENTENCE 0x00080000
48+
#define CLAUSE_TYPE_EOF 0x00010000
49+
50+
#define CLAUSE_INTONATION_TYPE 0x00007000
51+
#define CLAUSE_PAUSE 0x00000FFF
4852

4953
#define CLAUSE_PERIOD (40 | CLAUSE_INTONATION_FULL_STOP | CLAUSE_TYPE_SENTENCE)
5054
#define CLAUSE_COMMA (20 | CLAUSE_INTONATION_COMMA | CLAUSE_TYPE_CLAUSE)
@@ -54,6 +58,11 @@ Ort::Env ort_env{ORT_LOGGING_LEVEL_WARNING, "piper"};
5458
#define CLAUSE_COLON (30 | CLAUSE_INTONATION_FULL_STOP | CLAUSE_TYPE_CLAUSE)
5559
#define CLAUSE_SEMICOLON (30 | CLAUSE_INTONATION_COMMA | CLAUSE_TYPE_CLAUSE)
5660

61+
#define EXCLAMATION_PAUSE (CLAUSE_EXCLAMATION & CLAUSE_PAUSE)
62+
#define PERIOD_PAUSE (CLAUSE_PERIOD & CLAUSE_PAUSE)
63+
#define SEMICOLON_PAUSE (CLAUSE_SEMICOLON & CLAUSE_PAUSE)
64+
#define COMMA_PAUSE (CLAUSE_COMMA & CLAUSE_PAUSE)
65+
5766
struct piper_synthesizer {
5867
// From config JSON file
5968
std::string espeak_voice;

libpiper/src/piper.cpp

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,29 @@ piper_default_synthesize_options(piper_synthesizer *synth) {
129129
return options;
130130
}
131131

132+
std::string categorize_terminator(int terminator) {
133+
if ((terminator & CLAUSE_TYPE_EOF) != CLAUSE_TYPE_EOF) {
134+
int pause = terminator & CLAUSE_PAUSE;
135+
136+
if (pause >= PERIOD_PAUSE) {
137+
switch (terminator & CLAUSE_INTONATION_TYPE) {
138+
case CLAUSE_INTONATION_EXCLAMATION: return "!";
139+
case CLAUSE_INTONATION_QUESTION: return "?";
140+
default: return ".";
141+
}
142+
} else if (pause >= SEMICOLON_PAUSE) {
143+
switch (terminator & CLAUSE_INTONATION_TYPE) {
144+
case CLAUSE_INTONATION_FULL_STOP: return ":";
145+
default: return ";";
146+
}
147+
} else if (pause >= COMMA_PAUSE) {
148+
return ",";
149+
}
150+
}
151+
152+
return "";
153+
}
154+
132155
int piper_synthesize_start(struct piper_synthesizer *synth, const char *text,
133156
const piper_synthesize_options *options) {
134157
if (!synth) {
@@ -163,7 +186,6 @@ int piper_synthesize_start(struct piper_synthesizer *synth, const char *text,
163186
const void *text_ptr = text;
164187
while (text_ptr != nullptr) {
165188
int terminator = 0;
166-
std::string terminator_str = "";
167189

168190
const char *phonemes = espeak_TextToPhonemesWithTerminator(
169191
&text_ptr, espeakCHARS_AUTO, espeakPHONEMES_IPA, &terminator);
@@ -172,22 +194,7 @@ int piper_synthesize_start(struct piper_synthesizer *synth, const char *text,
172194
sentence_phonemes[current_idx] += phonemes;
173195
}
174196

175-
// Categorize terminator
176-
terminator &= 0x000FFFFF;
177-
178-
if (terminator == CLAUSE_PERIOD) {
179-
terminator_str = ".";
180-
} else if (terminator == CLAUSE_QUESTION) {
181-
terminator_str = "?";
182-
} else if (terminator == CLAUSE_EXCLAMATION) {
183-
terminator_str = "!";
184-
} else if (terminator == CLAUSE_COMMA) {
185-
terminator_str = ", ";
186-
} else if (terminator == CLAUSE_COLON) {
187-
terminator_str = ": ";
188-
} else if (terminator == CLAUSE_SEMICOLON) {
189-
terminator_str = "; ";
190-
}
197+
std::string terminator_str = categorize_terminator(terminator);
191198

192199
sentence_phonemes[current_idx] += terminator_str;
193200

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ exclude = '''
88
\.pyi$
99
)
1010
'''
11+
12+
[tool.pytest.ini_options]
13+
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = true

src/piper/espeakbridge.c

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,29 @@ static PyObject *py_set_voice(PyObject *self, PyObject *args) {
5757
Py_RETURN_NONE;
5858
}
5959

60+
static char *categorize_terminator(int terminator) {
61+
if ((terminator & CLAUSE_TYPE_EOF) != CLAUSE_TYPE_EOF) {
62+
int pause = terminator & CLAUSE_PAUSE;
63+
64+
if (pause >= PERIOD_PAUSE) {
65+
switch (terminator & CLAUSE_INTONATION_TYPE) {
66+
case CLAUSE_INTONATION_EXCLAMATION: return "!";
67+
case CLAUSE_INTONATION_QUESTION: return "?";
68+
default: return ".";
69+
}
70+
} else if (pause >= SEMICOLON_PAUSE) {
71+
switch (terminator & CLAUSE_INTONATION_TYPE) {
72+
case CLAUSE_INTONATION_FULL_STOP: return ":";
73+
default: return ";";
74+
}
75+
} else if (pause >= COMMA_PAUSE) {
76+
return ",";
77+
}
78+
}
79+
80+
return "";
81+
}
82+
6083
static PyObject *py_get_phonemes(PyObject *self, PyObject *args) {
6184
const char *text;
6285
if (!PyArg_ParseTuple(args, "s", &text)) {
@@ -67,42 +90,19 @@ static PyObject *py_get_phonemes(PyObject *self, PyObject *args) {
6790

6891
while (text != NULL) {
6992
int terminator = 0;
70-
char *terminator_str = "";
7193

7294
const char *phonemes = espeak_TextToPhonemesWithTerminator(
7395
(const void **)&text, espeakCHARS_AUTO, espeakPHONEMES_IPA,
7496
&terminator);
7597

76-
if (!(terminator & CLAUSE_TYPE_EOF)) {
77-
int pause = terminator & CLAUSE_PAUSE;
78-
int intonation = terminator & CLAUSE_INTONATION_TYPE;
79-
80-
if (pause >= PERIOD_PAUSE) {
81-
if (intonation == CLAUSE_INTONATION_EXCLAMATION) {
82-
terminator_str = "!";
83-
} else if (intonation == CLAUSE_INTONATION_QUESTION) {
84-
terminator_str = "?";
85-
} else {
86-
terminator_str = ".";
87-
}
88-
} else if (pause >= SEMICOLON_PAUSE) {
89-
if (intonation == CLAUSE_INTONATION_FULL_STOP) {
90-
terminator_str = ":";
91-
} else {
92-
terminator_str = ";";
93-
}
94-
} else if (pause >= COMMA_PAUSE) {
95-
terminator_str = ",";
96-
}
97-
}
98+
char *terminator_str = categorize_terminator(terminator);
9899

99100
PyList_Append(phonemes_and_terminators,
100101
Py_BuildValue("(ssO)", phonemes, terminator_str,
101102
(terminator & CLAUSE_TYPE_SENTENCE) ==
102103
CLAUSE_TYPE_SENTENCE
103104
? Py_True
104-
: Py_False
105-
));
105+
: Py_False));
106106
}
107107

108108
return phonemes_and_terminators;

tests/test_espeakbridge.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
@pytest.mark.parametrize("locale,text,expect", terminator_tests)
2828
def test_get_phonemes_terminator(locale: str, text: str, expect: list[str]):
2929
espeakbridge.set_voice(locale)
30-
3130
result = espeakbridge.get_phonemes(text)
3231

33-
assert [result[i][1] for i in range(len(result)) if result[i][1]] == expect
32+
assert [terminator for _, terminator, *_ in result] == expect

0 commit comments

Comments
 (0)