1 /* ----------------------------------------------------------------- */
2 /* The HMM-Based Speech Synthesis Engine "hts_engine API" */
3 /* developed by HTS Working Group */
4 /* http://hts-engine.sourceforge.net/ */
5 /* ----------------------------------------------------------------- */
6 /* */
7 /* Copyright (c) 2001-2015 Nagoya Institute of Technology */
8 /* Department of Computer Science */
9 /* */
10 /* 2001-2008 Tokyo Institute of Technology */
11 /* Interdisciplinary Graduate School of */
12 /* Science and Engineering */
13 /* */
14 /* All rights reserved. */
15 /* */
16 /* Redistribution and use in source and binary forms, with or */
17 /* without modification, are permitted provided that the following */
18 /* conditions are met: */
19 /* */
20 /* - Redistributions of source code must retain the above copyright */
21 /* notice, this list of conditions and the following disclaimer. */
22 /* - Redistributions in binary form must reproduce the above */
23 /* copyright notice, this list of conditions and the following */
24 /* disclaimer in the documentation and/or other materials provided */
25 /* with the distribution. */
26 /* - Neither the name of the HTS working group nor the names of its */
27 /* contributors may be used to endorse or promote products derived */
28 /* from this software without specific prior written permission. */
29 /* */
30 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND */
31 /* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, */
32 /* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
33 /* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
34 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS */
35 /* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */
36 /* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
37 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
38 /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
39 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */
40 /* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY */
41 /* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
42 /* POSSIBILITY OF SUCH DAMAGE. */
43 /* ----------------------------------------------------------------- */
44
45 #ifndef HTS_LABEL_C
46 #define HTS_LABEL_C
47
48 #ifdef __cplusplus
49 #define HTS_LABEL_C_START extern "C" {
50 #define HTS_LABEL_C_END }
51 #else
52 #define HTS_LABEL_C_START
53 #define HTS_LABEL_C_END
54 #endif /* __CPLUSPLUS */
55
56 HTS_LABEL_C_START;
57
58 #include <stdlib.h> /* for atof() */
59 #include <ctype.h> /* for isgraph(),isdigit() */
60
61 /* hts_engine libraries */
62 #include "HTS_hidden.h"
63
isdigit_string(char * str)64 static HTS_Boolean isdigit_string(char *str)
65 {
66 int i;
67
68 if (sscanf(str, "%d", &i) == 1)
69 return TRUE;
70 else
71 return FALSE;
72 }
73
74 /* HTS_Label_initialize: initialize label */
HTS_Label_initialize(HTS_Label * label)75 void HTS_Label_initialize(HTS_Label * label)
76 {
77 label->head = NULL;
78 label->size = 0;
79 }
80
81 /* HTS_Label_check_time: check label */
HTS_Label_check_time(HTS_Label * label)82 static void HTS_Label_check_time(HTS_Label * label)
83 {
84 HTS_LabelString *lstring = label->head;
85 HTS_LabelString *next = NULL;
86
87 if (lstring)
88 lstring->start = 0.0;
89 while (lstring) {
90 next = lstring->next;
91 if (!next)
92 break;
93 if (lstring->end < 0.0 && next->start >= 0.0)
94 lstring->end = next->start;
95 else if (lstring->end >= 0.0 && next->start < 0.0)
96 next->start = lstring->end;
97 if (lstring->start < 0.0)
98 lstring->start = -1.0;
99 if (lstring->end < 0.0)
100 lstring->end = -1.0;
101 lstring = next;
102 }
103 }
104
105 /* HTS_Label_load: load label */
HTS_Label_load(HTS_Label * label,size_t sampling_rate,size_t fperiod,HTS_File * fp)106 static void HTS_Label_load(HTS_Label * label, size_t sampling_rate, size_t fperiod, HTS_File * fp)
107 {
108 char buff[HTS_MAXBUFLEN];
109 HTS_LabelString *lstring = NULL;
110 double start, end;
111 const double rate = (double) sampling_rate / ((double) fperiod * 1e+7);
112
113 if (label->head || label->size != 0) {
114 HTS_error(1, "HTS_Label_load_from_fp: label is not initialized.\n");
115 return;
116 }
117
118 /* parse label file */
119 while (HTS_get_token_from_fp(fp, buff)) {
120 if (!isgraph((int) buff[0]))
121 break;
122 label->size++;
123
124 if (lstring) {
125 lstring->next = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
126 lstring = lstring->next;
127 } else { /* first time */
128 lstring = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
129 label->head = lstring;
130 }
131 if (isdigit_string(buff)) { /* has frame infomation */
132 start = atof(buff);
133 HTS_get_token_from_fp(fp, buff);
134 end = atof(buff);
135 HTS_get_token_from_fp(fp, buff);
136 lstring->start = rate * start;
137 lstring->end = rate * end;
138 } else {
139 lstring->start = -1.0;
140 lstring->end = -1.0;
141 }
142 lstring->next = NULL;
143 lstring->name = HTS_strdup(buff);
144 }
145 HTS_Label_check_time(label);
146 }
147
148 /* HTS_Label_load_from_fn: load label from file name */
HTS_Label_load_from_fn(HTS_Label * label,size_t sampling_rate,size_t fperiod,const char * fn)149 void HTS_Label_load_from_fn(HTS_Label * label, size_t sampling_rate, size_t fperiod, const char *fn)
150 {
151 HTS_File *fp = HTS_fopen_from_fn(fn, "r");
152 HTS_Label_load(label, sampling_rate, fperiod, fp);
153 HTS_fclose(fp);
154 }
155
156 /* HTS_Label_load_from_strings: load label from strings */
HTS_Label_load_from_strings(HTS_Label * label,size_t sampling_rate,size_t fperiod,char ** lines,size_t num_lines)157 void HTS_Label_load_from_strings(HTS_Label * label, size_t sampling_rate, size_t fperiod, char **lines, size_t num_lines)
158 {
159 char buff[HTS_MAXBUFLEN];
160 HTS_LabelString *lstring = NULL;
161 size_t i;
162 size_t data_index;
163 double start, end;
164 const double rate = (double) sampling_rate / ((double) fperiod * 1e+7);
165
166 if (label->head || label->size != 0) {
167 HTS_error(1, "HTS_Label_load_from_fp: label list is not initialized.\n");
168 return;
169 }
170 /* copy label */
171 for (i = 0; i < num_lines; i++) {
172 if (!isgraph((int) lines[i][0]))
173 break;
174 label->size++;
175
176 if (lstring) {
177 lstring->next = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
178 lstring = lstring->next;
179 } else { /* first time */
180 lstring = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
181 label->head = lstring;
182 }
183 data_index = 0;
184 if (isdigit_string(lines[i])) { /* has frame infomation */
185 HTS_get_token_from_string(lines[i], &data_index, buff);
186 start = atof(buff);
187 HTS_get_token_from_string(lines[i], &data_index, buff);
188 end = atof(buff);
189 HTS_get_token_from_string(lines[i], &data_index, buff);
190 lstring->name = HTS_strdup(buff);
191 lstring->start = rate * start;
192 lstring->end = rate * end;
193 } else {
194 lstring->start = -1.0;
195 lstring->end = -1.0;
196 lstring->name = HTS_strdup(lines[i]);
197 }
198 lstring->next = NULL;
199 }
200 HTS_Label_check_time(label);
201 }
202
203 /* HTS_Label_get_size: get number of label string */
HTS_Label_get_size(HTS_Label * label)204 size_t HTS_Label_get_size(HTS_Label * label)
205 {
206 return label->size;
207 }
208
209 /* HTS_Label_get_string: get label string */
HTS_Label_get_string(HTS_Label * label,size_t index)210 const char *HTS_Label_get_string(HTS_Label * label, size_t index)
211 {
212 size_t i;
213 HTS_LabelString *lstring = label->head;
214
215 for (i = 0; i < index && lstring; i++)
216 lstring = lstring->next;
217 if (!lstring)
218 return NULL;
219 return lstring->name;
220 }
221
222 /* HTS_Label_get_start_frame: get start frame */
HTS_Label_get_start_frame(HTS_Label * label,size_t index)223 double HTS_Label_get_start_frame(HTS_Label * label, size_t index)
224 {
225 size_t i;
226 HTS_LabelString *lstring = label->head;
227
228 for (i = 0; i < index && lstring; i++)
229 lstring = lstring->next;
230 if (!lstring)
231 return -1.0;
232 return lstring->start;
233 }
234
235 /* HTS_Label_get_end_frame: get end frame */
HTS_Label_get_end_frame(HTS_Label * label,size_t index)236 double HTS_Label_get_end_frame(HTS_Label * label, size_t index)
237 {
238 size_t i;
239 HTS_LabelString *lstring = label->head;
240
241 for (i = 0; i < index && lstring; i++)
242 lstring = lstring->next;
243 if (!lstring)
244 return -1.0;
245 return lstring->end;
246 }
247
248 /* HTS_Label_clear: free label */
HTS_Label_clear(HTS_Label * label)249 void HTS_Label_clear(HTS_Label * label)
250 {
251 HTS_LabelString *lstring, *next_lstring;
252
253 for (lstring = label->head; lstring; lstring = next_lstring) {
254 next_lstring = lstring->next;
255 HTS_free(lstring->name);
256 HTS_free(lstring);
257 }
258 HTS_Label_initialize(label);
259 }
260
261 HTS_LABEL_C_END;
262
263 #endif /* !HTS_LABEL_C */
264