-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathTTSTrie.cpp
197 lines (168 loc) · 5.79 KB
/
TTSTrie.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
//OK--//unsigned char turkce char icin
/**
* Implementation of TTSTrie class
*/
#include "TTSTrie.h"
/**
* TTSTrie: Constructor
* Action: Initializes TTSTrie object with default values, sets characters
* for each element in the trie nodes, sets offset and size to -1.
* Parameters: -
* Returns: -
* Comments: -
*/
TTSTrie::TTSTrie() {
InitTrieFromFile();
}
TTSTrie::~TTSTrie() {
}
int TTSTrie::Char2Pos(char c){
//turkish characters are represented as negative numbers
//so check if letter is Turkish
if((int)(c) < 0) {
switch(c) {
case 'ç': return 26;
case 'ð': return 27;
case 'ý': return 28;
case 'ö': return 29;
case 'þ': return 30;
case 'ü': return 31;
case 'â': return 32;
case 'î': return 33;
case 'û': return 34;
}
} else { //if english letter then put as it is
return (int(c) - int('a'));
}
}
/**
* InitTrieFromFile:
* Action: Initializes TTSTrie object with values gathered from TTS_TRIE_DATA_FILE,
* sets characters, offsets and sizes.
* Parameters: -
* Returns: -
* Comments: For now data file should have all data in lowercase letters.
*/
void TTSTrie::InitTrie() {
int i, j, k, l;
for(i=0;i<TTS_TRIE_NODE_ELEMENT_COUNT; i++) {
rootNode.elements[i].fileOffset = -1;
rootNode.elements[i].size = -1;
for(j = 0; j< TTS_TRIE_NODE_ELEMENT_COUNT; j++) {
level1Nodes[i].elements[j].fileOffset = -1;
level1Nodes[i].elements[j].size = -1;
for(k = 0; k< TTS_TRIE_NODE_ELEMENT_COUNT; k++) {
level2Nodes[i][j].elements[k].fileOffset = -1;
level2Nodes[i][j].elements[k].size = -1;
for(l = 0; l< TTS_TRIE_NODE_ELEMENT_COUNT; l++) {
level3Nodes[i][j][k].elements[l].fileOffset = -1;
level3Nodes[i][j][k].elements[l].size = -1;
}
}
}
}
}
void TTSTrie::InitTrieFromFile() {
TCHAR *fileName = _T(TTS_TRIE_DATA_FILE);
TTSTrieElement temp; //temporary TTSTrieElement
FILE * fp = NULL;
TCHAR input[256];
int letterCount,//letter count in a phone path
result,
offset,
size;
//opening file
if( (fp = _tfopen(fileName, "r")) ==NULL )
{
TTSError::ShowError(TTSError::TTS_FILE_NOT_FOUND_ERR);
return;
}
//getting information from file and initializing trie elements in each node
do {
result = _ftscanf(fp, "%d", &letterCount); //number of letters in the phone path
if(result == EOF) break;
_ftscanf(fp, "%s", input) ; //get phone/diphone/triphone
_ftscanf(fp, "%d", &offset); //get offset
_ftscanf(fp, "%d", &size); //get size
//set offset and size value for element
temp.fileOffset = offset;
temp.size = size;
//set element
SetTrieElement(input,temp);
}while(1);
//finished, close the open doors pls.
fclose(fp);
}//end InitFromFile()
/**
* GetTrieElement:
* Action: Retrieves a trie element for given index values.
* Parameters:
rootIndex: Index number of the element at root level
level1Index: Index number of the element at inner level
level2Index: Index number of the element at leaf level
***If the element is in an inner level node, then level2Index is -1.
***If the element is in root node, then level2Index and level1Index is -1.
* Returns: Pointer to the requested element.
* Comments: -
*/
TTSTrieElement * TTSTrie::GetTrieElement(string item) {
int length = (int)item.length();
if (length == 1) {
return &(rootNode.elements[Char2Pos(item[0])]);
} else if (length == 2) {
return &(level1Nodes[Char2Pos(item[0])].elements[Char2Pos(item[1])]);
} else if (length == 3) {
return &(level2Nodes[Char2Pos(item[0])][Char2Pos(item[1])].elements[Char2Pos(item[2])]);
} else if (length == 4) {
return &(level3Nodes[Char2Pos(item[0])][Char2Pos(item[1])][Char2Pos(item[2])].elements[Char2Pos(item[3])]);
}else
return NULL;
}//end GetTrieElement()
/**
* SetTrieElement:
* Action: Sets an element of given indexes according to a new given element
* Parameters:
rootIndex: Index number of the element at root level
level1Index: Index number of the element at inner level
level2Index: Index number of the element at leaf level
TElement: New element for given indexes.
***If the element is in an inner level node, then level2Index is -1.
***If the element is in root node, then level2Index and level1Index is -1.
* Returns: -
* Comments: -
*/
void TTSTrie::SetTrieElement(string item, TTSTrieElement TElement) {
int length = (int)item.length();
if (length == 1) {
rootNode.elements[Char2Pos(item[0])].fileOffset = TElement.fileOffset;
rootNode.elements[Char2Pos(item[0])].size = TElement.size;
} else if (length == 2) {
level1Nodes[Char2Pos(item[0])].elements[Char2Pos(item[1])].fileOffset = TElement.fileOffset;
level1Nodes[Char2Pos(item[0])].elements[Char2Pos(item[1])].size = TElement.size;
} else if (length == 3) {
level2Nodes[Char2Pos(item[0])][Char2Pos(item[1])].elements[Char2Pos(item[2])].fileOffset = TElement.fileOffset;
level2Nodes[Char2Pos(item[0])][Char2Pos(item[1])].elements[Char2Pos(item[2])].size = TElement.size;
} else if (length == 4) {
level3Nodes[Char2Pos(item[0])][Char2Pos(item[1])][Char2Pos(item[2])].elements[Char2Pos(item[3])].fileOffset = TElement.fileOffset;
level3Nodes[Char2Pos(item[0])][Char2Pos(item[1])][Char2Pos(item[2])].elements[Char2Pos(item[3])].size = TElement.size;
}
}//end SetTrieElement()
/**
* TTS Trie node search method,
* searches the nodes of the Trie and returns true/false
* according to the existance of the input
*/
bool TTSTrie::exists(string item)
{
int length = (int)item.length();
if (length == 1) {
return rootNode.elements[Char2Pos(item[0])].size > 0;
} else if (length == 2) {
return level1Nodes[Char2Pos(item[0])].elements[Char2Pos(item[1])].size > 0;
} else if (length == 3) {
return level2Nodes[Char2Pos(item[0])][Char2Pos(item[1])].elements[Char2Pos(item[2])].size > 0;
} else if (length == 4) {
return level3Nodes[Char2Pos(item[0])][Char2Pos(item[1])][Char2Pos(item[2])].elements[Char2Pos(item[3])].size > 0;
}else
return false;
}