Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
TensorSpeech
GitHub Repository: TensorSpeech/TensorFlowTTS
Path: blob/master/examples/cppwin/TensorflowTTSCppInference/phonemizer.cpp
1559 views
1
#include "phonemizer.h"
2
#include <fstream>
3
#include "ext/ZCharScanner.h"
4
5
int32_t GetID(const std::vector<IdStr>& In, const std::string &InStr)
6
{
7
for (const IdStr& It : In)
8
if (It.STR == InStr)
9
return It.ID;
10
11
return -1;
12
}
13
14
std::string GetSTR(const std::vector<IdStr>& In, int32_t InID)
15
{
16
for (const IdStr& It : In)
17
if (It.ID == InID)
18
return It.STR;
19
20
return "";
21
22
}
23
24
std::vector<IdStr> Phonemizer::GetDelimitedFile(const std::string &InFname)
25
{
26
27
28
std::ifstream InFile (InFname);
29
30
int32_t CuID;
31
std::string Tok;
32
std::vector<IdStr> RetVec;
33
34
35
std::string Line;
36
while (std::getline(InFile, Line)) {
37
38
if (Line.find("\t") == std::string::npos)
39
continue;
40
41
42
ZStringDelimiter Deline(Line);
43
Deline.AddDelimiter("\t");
44
45
CuID = stoi(Deline[1]);
46
Tok = Deline[0];
47
48
49
RetVec.push_back(IdStr{CuID,Tok});
50
51
}
52
53
return RetVec;
54
55
56
}
57
58
void Phonemizer::LoadDictionary(const std::string &InDictFn)
59
{
60
61
62
63
std::ifstream InFile (InDictFn);
64
65
std::string Word;
66
std::string Phn;
67
68
69
if (Dictionary.size())
70
Dictionary.clear();
71
72
73
74
75
std::string Line;
76
while (std::getline(InFile, Line)) {
77
78
if (Line.find("\t") == std::string::npos)
79
continue;
80
81
82
ZStringDelimiter Deline(Line);
83
Deline.AddDelimiter("\t");
84
85
Word = Deline[0];
86
Phn = Deline[1];
87
88
89
Dictionary.push_back(StrStr{Word,Phn});
90
91
}
92
// Sort so lookup can be a bit optimized
93
std::sort(Dictionary.begin(),Dictionary.end());
94
95
96
}
97
98
std::string Phonemizer::DictLookup(const std::string &InWord)
99
{
100
101
for (size_t w = 0 ; w < Dictionary.size();w++)
102
{
103
const StrStr& Entr = Dictionary[w];
104
105
if (Entr.Word.size() != InWord.size())
106
continue;
107
108
if (Entr.Word == InWord)
109
return Entr.Phn;
110
111
}
112
113
return "";
114
115
}
116
117
118
119
120
Phonemizer::Phonemizer()
121
{
122
123
}
124
125
bool Phonemizer::Initialize(const std::string InPath)
126
{
127
// Load indices
128
try {
129
CharId = GetDelimitedFile(InPath + "/char2id.txt");
130
PhnId = GetDelimitedFile(InPath + "/phn2id.txt");
131
132
// Load model
133
G2pModel.Initialize(InPath + "/model");
134
135
LoadDictionary(InPath + "/dict.txt");
136
}
137
catch (...){
138
return false;
139
}
140
141
142
143
144
return true;
145
146
147
}
148
149
std::string Phonemizer::ProcessWord(const std::string &InWord,float Temperature)
150
{
151
// First we try dictionary lookup
152
// This is because the g2p model can be unreliable, we only want to use it for novel sentences
153
154
std::string PhnDict = DictLookup(InWord);
155
if (!PhnDict.empty())
156
return PhnDict;
157
158
std::vector<int32_t> InIndexes;
159
InIndexes.reserve(InWord.size());
160
161
// Turn word into indices
162
for (const char ch : InWord)
163
{
164
std::string Single(1,ch);
165
int32_t Idx = GetID(CharId,Single);
166
167
if (Idx != -1)
168
InIndexes.push_back(Idx);
169
170
171
}
172
173
TFTensor<int32_t> PhnPrediction = G2pModel.DoInference(InIndexes,Temperature);
174
175
176
std::string RetStr = "";
177
bool FirstIter = true;
178
179
for (int32_t PhnIdx : PhnPrediction.Data)
180
{
181
std::string PhnTxt = GetSTR(PhnId,PhnIdx);
182
if (!PhnTxt.empty())
183
{
184
if (!FirstIter)
185
RetStr.append(" ");
186
187
RetStr.append(PhnTxt);
188
189
}
190
191
FirstIter = false;
192
}
193
194
195
196
return RetStr;
197
198
}
199
200
std::string Phonemizer::GetPhnLanguage() const
201
{
202
return PhnLanguage;
203
}
204
205
void Phonemizer::SetPhnLanguage(const std::string &value)
206
{
207
208
PhnLanguage = value;
209
}
210
211
std::string Phonemizer::GetGraphemeChars()
212
{
213
214
std::string RetAllowed = "";
215
for (const IdStr& Idx : CharId)
216
RetAllowed.append(Idx.STR);
217
218
return RetAllowed;
219
220
}
221
222
223
224
225
bool operator<(const StrStr &right, const StrStr &left)
226
{
227
return right.Word.length() < left.Word.length();
228
}
229
230