This repository was archived by the owner on Apr 5, 2026. It is now read-only.
forked from rhasspy/piper
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathphonemize.hpp
More file actions
108 lines (83 loc) · 2.99 KB
/
Copy pathphonemize.hpp
File metadata and controls
108 lines (83 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#ifndef PHONEMIZE_H_
#define PHONEMIZE_H_
#include <filesystem>
#include <iostream>
#include <map>
#include <set>
#include <stdexcept>
#include <string>
#include <vector>
#include <espeak-ng/speak_lib.h>
#include "config.hpp"
#include "utf8.h"
using namespace std;
namespace piper {
// Text to phonemes using eSpeak-ng
void phonemize(PhonemizeConfig &phonemizeConfig) {
if (!phonemizeConfig.eSpeak) {
throw runtime_error("Missing eSpeak config");
}
if (!phonemizeConfig.phonemes) {
phonemizeConfig.phonemes.emplace();
}
auto voice = phonemizeConfig.eSpeak->voice;
int result = espeak_SetVoiceByName(voice.c_str());
if (result != 0) {
throw runtime_error("Failed to set eSpeak-ng voice");
}
string text(phonemizeConfig.text);
vector<char32_t> textClauseBreakers;
utf8::iterator textIter(text.begin(), text.begin(), text.end());
utf8::iterator textIterEnd(text.end(), text.begin(), text.end());
while (textIter != textIterEnd) {
auto codepoint = *textIter;
if (phonemizeConfig.eSpeak->clauseBreakers.contains(codepoint)) {
textClauseBreakers.push_back(codepoint);
}
textIter++;
}
const char *inputTextPointer = text.c_str();
size_t clauseBreakerIndex = 0;
while (inputTextPointer != NULL) {
string clausePhonemes(
espeak_TextToPhonemes((const void **)&inputTextPointer,
/*textmode*/ espeakCHARS_AUTO,
/*phonememode = IPA*/ 0x02));
utf8::iterator phonemeIter(clausePhonemes.begin(), clausePhonemes.begin(),
clausePhonemes.end());
utf8::iterator phonemeEnd(clausePhonemes.end(), clausePhonemes.begin(),
clausePhonemes.end());
phonemizeConfig.phonemes->insert(phonemizeConfig.phonemes->end(),
phonemeIter, phonemeEnd);
if (clauseBreakerIndex < textClauseBreakers.size()) {
phonemizeConfig.phonemes->push_back(
textClauseBreakers[clauseBreakerIndex]);
clauseBreakerIndex++;
}
}
} /* phonemize */
// Phonemes to ids using JSON map
void phonemes2ids(PhonemizeConfig &phonemizeConfig,
SynthesisConfig &synthesisConfig) {
if (!phonemizeConfig.phonemes) {
throw runtime_error("No phonemes present");
}
synthesisConfig.phonemeIds.push_back(phonemizeConfig.idBos);
if (phonemizeConfig.interspersePad) {
synthesisConfig.phonemeIds.push_back(phonemizeConfig.idPad);
}
for (auto phoneme = phonemizeConfig.phonemes->begin();
phoneme != phonemizeConfig.phonemes->end(); phoneme++) {
if (phonemizeConfig.phonemeIdMap.contains(*phoneme)) {
for (auto id : phonemizeConfig.phonemeIdMap[*phoneme]) {
synthesisConfig.phonemeIds.push_back(id);
if (phonemizeConfig.interspersePad) {
synthesisConfig.phonemeIds.push_back(phonemizeConfig.idPad);
}
}
}
}
synthesisConfig.phonemeIds.push_back(phonemizeConfig.idEos);
} /* phonemes2ids */
} // namespace piper
#endif // PHONEMIZE_H_