-
Notifications
You must be signed in to change notification settings - Fork 20
/
espeakphonemizer.cpp
113 lines (71 loc) · 2.46 KB
/
espeakphonemizer.cpp
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
109
110
111
112
#include "espeakphonemizer.h"
#include <espeak/speak_lib.h>
static const std::u32string Punctuation_t = U",.;¡!¿?:-~";
static const std::u32string Punctuation_ns = U"¿-~";
using namespace ESP;
std::string ESpeakPhonemizer::ToPhon(const std::string &InTxt)
{
const char* TextPtr = InTxt.c_str();
const void** OurPtr = (const void**)&TextPtr;
const char* Phon = espeak_TextToPhonemes(OurPtr, espeakCHARS_AUTO, (int)PhonemePars.to_ulong());
return std::string(Phon);
}
void ESpeakPhonemizer::Initialize(const std::string &DataPath, const std::string &VoiceName)
{
// these are irrelevant because we don't play any audio, we just use the phonemizer
espeak_AUDIO_OUTPUT output = AUDIO_OUTPUT_SYNCH_PLAYBACK;
int buflength = 500, options = 0;
auto Err1 = espeak_Initialize(output, buflength, DataPath.c_str(), options);
auto Err = espeak_SetVoiceByName(VoiceName.c_str());
EVoiceName = VoiceName;
PhonemePars[1] = 1; // set IPA
}
std::string ESpeakPhonemizer::Phonemize(const std::string &Input)
{
std::u32string In = VoxUtil::StrToU32(Input);
// ESpeak's phonemize function stops at punctuation, so we split it up into chunks, phonemize, then put them back together
PunctSplitVec SplitVec = IterativePunctuationSplit(In, Punctuation_t);
std::string Assembled = "";
bool Space = false;
for (const auto& Spli : SplitVec)
{
std::string Pibber = VoxUtil::U32ToStr(Spli.second);
if (!Spli.first)
{
Pibber = ToPhon(Pibber);
if (Space)
Assembled += " ";
}else
{
Space = true;
for (const auto& PCh : Punctuation_ns){
if (Spli.second.find(PCh) != std::u32string::npos)
Space = false;
}
}
Assembled += Pibber;
}
return Assembled;
}
ESpeakPhonemizer::ESpeakPhonemizer()
{
}
ESP::PunctSplitVec ESP::IterativePunctuationSplit(const std::u32string &Input, const std::u32string &Punct)
{
PunctSplitVec Ret;
std::u32string CuStr = U"";
for (const auto& Ch : Input) {
if (Punct.find(Ch) != std::u32string::npos) {
if (CuStr.size())
Ret.push_back({ false,CuStr });
std::u32string PunctOnly(1,Ch);
Ret.push_back({ true, PunctOnly });
CuStr = U"";
}
else {
CuStr += Ch;
}
}
Ret.push_back({ false,CuStr });
return Ret;
}